Description
Input
Output
每次x=1时,每行一个整数,表示这次旅行的开心度
Sample Input
4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
1 100 5 5
5
1 1 2
2 1 2
1 1 2
2 2 3
1 1 4
Sample Output
101
11
11
11
11
HINT
对于100%的数据, n ≤ 100000,m≤200000 ,data[i]非负且小于10^9
对于这个开方,一开始yy了好久,后来发现,10^9的数顶多开方六七次,就一直是1了,所以我们可以用all[id]=1表示该区间内所有数都已不用开方(开方了之后没区别)
写完之后一直TLE,内心崩溃,后来才发现,我把0给忘了。。。。。。
#include<cstdio>
#include<iostream>
#include<cmath>
#define p1 id<<1
#define p2 id<<1^1
using namespace std;
long long tree[410000];
int all[410000];
int a[100005];
int n,m,x,y,z;
void build(int id,int l,int r)
{
if(l==r)
{
tree[id]=a[l];
all[id]=0;
return;
}
int mid=(l+r)/2;
build(p1,l,mid);
build(p2,mid+1,r);
tree[id]=tree[p1]+tree[p2];
}
void update(int id,int l,int r,int x,int y)
{
if(x<=l&&r<=y&&all[id]==1) return;
if(l==r)
{
a[l]=(int)(sqrt(a[l]));
tree[id]=(long long)(a[l]);
if(a[l]<=1) all[id]=1;
return;
}
int mid=(l+r)/2;
if(y<=mid) update(p1,l,mid,x,y);
else
if(x>mid) update(p2,mid+1,r,x,y);
else
{
update(p1,l,mid,x,mid);
update(p2,mid+1,r,mid+1,y);
}
tree[id]=tree[p1]+tree[p2];
all[id]=(all[p1]&all[p2]);
}
long long query(int id,int l,int r,int x,int y)
{
if(x<=l&&r<=y) return tree[id];
int mid=(l+r)/2;
if(y<=mid) return query(p1,l,mid,x,y);
else
if(x>mid) return query(p2,mid+1,r,x,y);
else return query(p1,l,mid,x,mid)+query(p2,mid+1,r,mid+1,y);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
cin>>m;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&z,&x,&y);
if(z==1) printf("%lld\n",query(1,1,n,x,y));
if(z==2) update(1,1,n,x,y);
}
return 0;
}