Rikka with Sequence
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:
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?
Input
The first line contains a number t(1<=t<=100), the number of the testcases. And there are no more than 5 testcases with n>1000.
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.
Output
For each operation of type 3, print a lines contains one number -- the answer of the query.
Sample Input
1
5 5
1 2 3 4 5
1 3 5 2
2 1 4
3 2 4
2 3 5
3 1 5
Sample Output
5
6
线段树好题
这个本来按照区间开根的思想考虑了维护一段权重相同的值。
但最后这个被卡了
232323 +6 sqrt
然后:
维护区间Max-Min<=1的序列,这个序列讨论复杂度要低一些。
存在区间Set
所以注意先做set的lazy
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define lc (p<<1)
#define rc (p<<1|1)
const int N=2e5+1000;
typedef int INT;
#define int long long
inline void read(int &x){
x=0;
int f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-'){
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
x*=f;
}
int n,m;
int val[N]={};
struct Segment_Tree{
struct Node{
int sum,lson,rson,Mn,Mx,addlazy,setlazy;
}T[N<<2];
inline void PushUp(int p){
T[p].sum=T[lc].sum+T[rc].sum;
T[p].Mn=min(T[lc].Mn,T[rc].Mn);
T[p].Mx=max(T[lc].Mx,T[rc].Mx);
}
inline void PushNow(int p,int flag,int val){
if(flag==1){
T[p].sum+=(T[p].rson-T[p].lson+1)*val;
T[p].addlazy+=val;
T[p].Mx+=val;
T[p].Mn+=val;
}
else{
T[p].addlazy=0;
T[p].sum=(T[p].rson-T[p].lson+1)*val;
T[p].setlazy=val;
T[p].Mx=T[p].Mn=val;
}
}
inline void PushDown(int p){
if(T[p].setlazy!=-1){
PushNow(lc,0,T[p].setlazy);
PushNow(rc,0,T[p].setlazy);
T[p].setlazy=-1;
}
if(T[p].addlazy){
PushNow(lc,1,T[p].addlazy);
PushNow(rc,1,T[p].addlazy);
T[p].addlazy=0;
}
}
inline void Build(int p,int l,int r){
T[p].lson=l;
T[p].rson=r;
T[p].setlazy=-1;
T[p].addlazy=0;
if(l==r){
T[p].sum=T[p].Mn=T[p].Mx=val[l];
return;
}
int mid=(l+r)/2;
Build(lc,l,mid);
Build(rc,mid+1,r);
PushUp(p);
}
inline void update(int p,int l,int r,int val){
if(l<=T[p].lson&&T[p].rson<=r){
PushNow(p,1,val);
return;
}
PushDown(p);
int mid=(T[p].lson+T[p].rson)/2;
if(l<=mid)
update(lc,l,r,val);
if(mid< r)
update(rc,l,r,val);
PushUp(p);
}
inline void Sqr(int p,int l,int r){
if(l<=T[p].lson&&T[p].rson<=r&&T[p].Mx-T[p].Mn<=1){
int SqrMx=sqrt(T[p].Mx);
int SqrMn=sqrt(T[p].Mn);
if(SqrMx==SqrMn){
PushNow(p,0,SqrMx);
}
else{
PushNow(p,1,SqrMx-T[p].Mx);
}
}
else{
PushDown(p);
int mid=(T[p].lson+T[p].rson)/2;
if(l<=mid)
Sqr(lc,l,r);
if(mid<r )
Sqr(rc,l,r);
PushUp(p);
}
}
inline int Query(int p,int l,int r){
if(l<=T[p].lson&&T[p].rson<=r){
return T[p].sum;
}
PushDown(p);
int ret=0;
int mid=(T[p].lson+T[p].rson)/2;
if(l<=mid)ret+=Query(lc,l,r);
if(mid <r)ret+=Query(rc,l,r);
return ret;
}
}T;
INT main(){
// freopen("HDU5828.in","r",stdin);
int Case;
read(Case);
while(Case--){
read(n);
read(m);
for(int i=1;i<=n;i++){
read(val[i]);
}
T.Build(1,1,n);
// cout<<"here"<<'\n';
while(m--){
// cout<<m<<'\n';
int opt;
read(opt);
if(opt==1){
int l,r,val;
read(l);
read(r);
read(val);
T.update(1,l,r,val);
}
if(opt==2){
int l,r;
read(l);
read(r);
T.Sqr(1,l,r);
}
if(opt==3){
int l,r;
read(l);
read(r);
cout<<T.Query(1,l,r)<<'\n';
}
}
}
}