2016暑假多校联合---Rikka with Sequence (线段树)
Yuta has an array A with n numbers. Then he makes m operations on it.
There are three type of operations:
1 l r x : For each i in [l,r], change A[i] to A[i]+x
2 l r : For each i in [l,r], change A[i] to ⌊A−−√[i]⌋
3 l r : Yuta wants Rikka to sum up A[i] for all i in [l,r]
It is too difficult for Rikka. Can you help her?
For each testcase, the first line contains two numbers n,m(1<=n,m<=100000). The second line contains n numbers A[1]~A[n]. Then m lines follow, each line describe an operation.
It is guaranteed that 1<=A[i],x<=100000.
题意: 三种操作,1、区间上加上一个数;
2、区间上所有数开根号向下取整;
3、区间求和;
思路: 对于记录区间的最大值和最小值,如果相等的话,那么只需要对一个数开根号,算出开根号前后的差值,这样区间开根号就变成了区间减去一个数了;
由于是开根,所以存在两个数刚开始差为1,加上某数再开根依旧是差1,这样维护相同数区间的就没用了
比如(2,3) +6-->(8,9)开根-->(2,3)如果全是这样的操作,即使维护相同的数,每次开根的复杂度都是O(N),不T才怪
这样只需要维护区间最大值最小值,当差1的时候,看看是否开根后还是差1,如果还是差1,那么对区间开根号相当于整个区间减去同一个数,
这样就可以变开根为减了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
typedef long long LL;
const int BufferSize=<<;
char buffer[BufferSize],*head,*tail;
inline char Getchar()
{
if(head==tail)
{
int l=fread(buffer,,BufferSize,stdin);
tail=(head=buffer)+l;
}
return *head++;
}
inline int read()
{
int x=,f=;char c=Getchar();
for(;!isdigit(c);c=Getchar()) if(c=='-') f=-;
for(;isdigit(c);c=Getchar()) x=x*+c-'';
return x*f;
}
///----------------------------------------------------------------------
const int N=1e5+;
LL sum[N<<],lz[N<<],mx[N<<],mn[N<<]; void up(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
mx[rt]=max(mx[rt<<],mx[rt<<|]);
mn[rt]=min(mn[rt<<],mn[rt<<|]);
} void build(int rt,int l,int r)
{
lz[rt]=;
if(l==r){sum[rt]=read();mn[rt]=mx[rt]=sum[rt];return;}
int mid=l+r>>;
build(rt<<,l,mid);build(rt<<|,mid+,r);
up(rt);
} void down(int rt,int l,int r)
{
if(lz[rt]!=)
{
int mid=l+r>>;
lz[rt<<]+=lz[rt];
lz[rt<<|]+=lz[rt];
mn[rt<<]+=lz[rt];
mx[rt<<]+=lz[rt];
mx[rt<<|]+=lz[rt];
mn[rt<<|]+=lz[rt];
sum[rt<<]+=lz[rt]*(mid-l+);
sum[rt<<|]+=lz[rt]*(r-mid);
lz[rt]=;
}
} int x,y,t,T,n,m; void kaigen(int rt,int l,int r)
{
if(x<=l&&r<=y)
{
if(mx[rt]==mn[rt])
{
lz[rt]-=mx[rt];
mx[rt]=sqrt(mx[rt]);
mn[rt]=mx[rt];
lz[rt]+=mx[rt];
sum[rt]=mx[rt]*(r-l+);
return;
}
else if(mx[rt]==mn[rt]+)
{
LL x1=sqrt(mx[rt]);
LL x2=sqrt(mn[rt]);
if(x1==x2+)
{
lz[rt]-=(mx[rt]-x1);
sum[rt]-=(mx[rt]-x1)*(r-l+);
mx[rt]=x1;mn[rt]=x2;
return;
}
}
}
int mid=l+r>>;down(rt,l,r);
if(x<=mid)kaigen(rt<<,l,mid);
if(y>mid)kaigen(rt<<|,mid+,r);
up(rt);
} void add(int rt,int l,int r)
{
if(x<=l&&r<=y)
{
lz[rt]+=t;
sum[rt]+=(long long)(r-l+)*t;
mx[rt]+=t;mn[rt]+=t;
return ;
}
int mid=l+r>>;down(rt,l,r);
if(x<=mid)add(rt<<,l,mid);
if(y>mid)add(rt<<|,mid+,r);
up(rt);
} LL get(int rt,int l,int r)
{
if(x<=l&&r<=y)return sum[rt];
int mid=l+r>>;down(rt,l,r);
LL ret=;
if(x<=mid)ret+=get(rt<<,l,mid);
if(y>mid)ret+=get(rt<<|,mid+,r);
return ret;
} int main()
{
T=read();
while(T--)
{
n=read();m=read();
build(,,n);
while(m--)
{
int op;
op=read();x=read();y=read();
if(op==)
{
t=read();
add(,,n);
}
else if(op==)kaigen(,,n);
else printf("%I64d\n",get(,,n));
}
}
return ;
}
2016暑假多校联合---Rikka with Sequence (线段树)的更多相关文章
-
2016暑假多校联合---Windows 10
2016暑假多校联合---Windows 10(HDU:5802) Problem Description Long long ago, there was an old monk living on ...
-
2016暑假多校联合---Substring(后缀数组)
2016暑假多校联合---Substring Problem Description ?? is practicing his program skill, and now he is given a ...
-
2016暑假多校联合---To My Girlfriend
2016暑假多校联合---To My Girlfriend Problem Description Dear Guo I never forget the moment I met with you. ...
-
2016暑假多校联合---A Simple Chess
2016暑假多校联合---A Simple Chess Problem Description There is a n×m board, a chess want to go to the po ...
-
2016暑假多校联合---Another Meaning
2016暑假多校联合---Another Meaning Problem Description As is known to all, in many cases, a word has two m ...
-
hdu 5828 Rikka with Sequence 线段树
Rikka with Sequence 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5828 Description As we know, Rik ...
-
2016暑假多校联合---Death Sequence(递推、前向星)
原题链接 Problem Description You may heard of the Joseph Problem, the story comes from a Jewish historia ...
-
2016暑假多校联合---GCD
Problem Description Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). ...
-
2016暑假多校联合---Counting Intersections
原题链接 Problem Description Given some segments which are paralleled to the coordinate axis. You need t ...
随机推荐
-
C标准头文件<;errno.h>;
声明了错误处理相关的宏 errno errno即error number,在程序启动时被设为0,当某个库函数运行出现错误的时候,会将相应的能表达错误类型的数字赋值给这个左值,这些数字往往有相应的宏来表 ...
-
javascript数据结构与算法--链表
链表与数组的区别? 1. 定义: 数组又叫做顺序表,顺序表是在内存中开辟一段连续的空间来存储数据,数组可以处理一组数据类型相同的数据,但不允许动态定义数组的大小,即在使用数组之前必须确定数组的大小. ...
-
linux之od命令
od [OPTION]... [FILE]... 把文件用8进制或者其他的格式显示出来.通常用于查看特殊格式文件的内容. 这个命令默认把文件的内容用八进制的形式清晰地写在标准输出上.如果是多个文件 ...
-
ABBYY可以给我们解决那些问题
不同的行业组织和企业有不同的业务流程和规定,在OCR文字识别领域,ORC文字识别软件ABBYY给各个行业都提供了有效解决方案,满足其特定需求的同时还帮助他们提高业务流程处理效率,降低成本,全球大量的纸 ...
-
HDU-1896 Stones
http://acm.hdu.edu.cn/showproblem.php?pid=1896 题意:一个人从0开始走起,遇到偶数个石头就踢.要是同一位置有多个石头,则先扔最重的石头(也就是扔的最近的那 ...
-
cocos2d安装配置及打包成Android
vs+python+cocos2d python下载:点这里 这里需要下载Python 2.X版本.曾经以为要下载3.x版本 后来装上发现cocos2d-x提供的python运行报错,所以卸载以后重新 ...
-
Leetcode_111_Minimum Depth of Binary Tree
本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41964249 Minimum Depth of Binar ...
-
python 递归实现汉诺塔算法
def move(n,a,b,c): if (n == 1): print ( "第 ", n ," 步: 将盘子由 " ,a ," 移动到 &quo ...
-
2.1 Html
一.Head中常用标签 <head>元素出现在文档的开头部分,会书写一些和浏览器中的配置信息. <head>与</head>之间的内容不会在浏览器的文档窗口显示,但 ...
-
PLSQLDeveloper_免安装自带client
PLSQLDeveloper_解压版 免安装并且自带有client客户端. 要安装解压附带的readme.txt进行配置. 一. 目录结构 D:\install\PLSQL |-- instantcl ...