题目大意:给定一个序列,提供下列操作:
1.将[l.r]区间内每个数a[i]变为sqrt(a[i])
2.查询[l,r]区间的和
同BZOJ3211 花神游历各国
链接:http://blog.csdn.net/popoqqq/article/details/39961591
我这个沙茶居然两次挂在了同一个地方。。。妈蛋啊
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 100100 using namespace std; typedef long long ll; int n,m,fa[M]; ll a[M],c[M],ans; int Find(int x) { if(!fa[x]||fa[x]==x) return fa[x]=x; return fa[x]=Find(fa[x]); } void Update(int x,ll y) { for(;x<=n;x+=x&-x) c[x]+=y; } ll Get_Ans(int x) { ll re=0; for(;x;x-=x&-x) re+=c[x]; return re; } void Modify(int x,int y) { int i; for( i=Find(x) ; i<=y ; i=Find(i+1) ) { ll temp=(ll)sqrt(a[i]); Update(i,temp-a[i]); a[i]=temp; if(a[i]<=1) fa[i]=Find(i+1); } } int main() { int i,p,x,y; cin>>n; for(i=1;i<=n;i++) { scanf("%lld",&a[i]); if(a[i]<=1) fa[i]=i+1; Update(i,a[i]); } cin>>m; for(i=1;i<=m;i++) { scanf("%d%d%d",&p,&x,&y); if(x>y) swap(x,y); if(p==0) Modify(x,y); else printf("%lld\n", Get_Ans(y)-Get_Ans(x-1) ); } }