链接:戳这里
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
题意:
三个操作:
1 x y v 区间[x,y]值增加v
2 x y 区间[x,y]的值开根号
3 x y 查询区间[x,y]的和
思路:
额 由于开根号这个操作会使得数尽可能的趋于一致 ,然后直接暴力就可以,记录一下区间的数是否一样
(听说有人手构数据让标程T
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<iomanip>
#include<cmath>
#include<bitset>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
#define INF (1ll<<60)-1
#define Max 1e9
using namespace std;
const long double eps=1e-8;
ll lazy[500100],sum[500100],a[100100],same[500100];
void pushup(int root){
sum[root]=sum[root*2]+sum[root*2+1];
if(same[root*2]==same[root*2+1] && same[root*2])
same[root]=same[root*2];
else same[root]=0;
}
void build(int root,int l,int r){
same[root]=lazy[root]=0;
if(l==r){
sum[root]=a[l];
same[root]=a[l];
return ;
}
int mid=(l+r)/2;
build(root*2,l,mid);
build(root*2+1,mid+1,r);
pushup(root);
}
void pushdown(int root,int len){
if(same[root]){
same[root*2]=same[root*2+1]=same[root];
sum[root*2]=same[root]*1LL*(len-len/2);
sum[root*2+1]=same[root]*1LL*(len/2);
lazy[root]=0;
}
if(lazy[root]){
lazy[root*2]+=lazy[root];
lazy[root*2+1]+=lazy[root];
if(same[root*2]) same[root*2]+=lazy[root];
if(same[root*2+1]) same[root*2+1]+=lazy[root];
sum[root*2]+=1LL*(len-len/2)*lazy[root];
sum[root*2+1]+=1LL*(len/2)*lazy[root];
lazy[root]=0;
}
}
void update1(int root,int l,int r,int x,int y,ll v){
if(x<=l && y>=r){
sum[root]+=1LL*(r-l+1)*v;
lazy[root]+=v;
if(same[root]) same[root]+=v;
return ;
}
pushdown(root,r-l+1);
int mid=(l+r)/2;
if(y<=mid) update1(root*2,l,mid,x,y,v);
else if(x>mid) update1(root*2+1,mid+1,r,x,y,v);
else {
update1(root*2,l,mid,x,mid,v);
update1(root*2+1,mid+1,r,mid+1,y,v);
}
pushup(root);
}
void update2(int root,int l,int r,int x,int y){
if(x<=l && y>=r && same[root]){
same[root]=(ll)sqrt(1.0*same[root]+0.5);
sum[root]=1LL*(r-l+1)*same[root];
return ;
}
pushdown(root,r-l+1);
int mid=(l+r)/2;
if(y<=mid) update2(root*2,l,mid,x,y);
else if(x>mid) update2(root*2+1,mid+1,r,x,y);
else {
update2(root*2,l,mid,x,mid);
update2(root*2+1,mid+1,r,mid+1,y);
}
pushup(root);
}
ll query(int root,int l,int r,int x,int y){
if(x<=l && y>=r){
return sum[root];
}
int mid=(l+r)/2;
pushdown(root,r-l+1);
ll ans=0;
if(x<=mid) ans+=query(root*2,l,mid,x,y);
if(y>mid) ans+=query(root*2+1,mid+1,r,x,y);
return ans;
}
int n,m;
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
mst(sum,0);
mst(lazy,0);
mst(same,0);
for(int i=1;i<=n;i++) scanf("%I64d",&a[i]);
build(1,1,n);
for(int i=1;i<=m;i++){
int t,x,y;
ll v;
scanf("%d",&t);
if(t==1){
scanf("%d%d%I64d",&x,&y,&v);
update1(1,1,n,x,y,v);
} else if(t==2){
scanf("%d%d",&x,&y);
update2(1,1,n,x,y);
} else {
scanf("%d%d",&x,&y);
printf("%I64d\n",query(1,1,n,x,y));
}
}
}
return 0;
}