spoj 2713 Can you answer these queries IV
http://www.spoj.pl/problems/GSS4/
题意:给一个数列,有两个操作:
0 L,R,把区间[L,R]内的数开平方。
1 L,R,求区间[L,R]的和。
思路:因为一个1e18的数开方8次后必为1,所以时间复杂度为O(8*n+n*log(n))。
View Code
#include<stdio.h> #include<string.h> #include<iostream> #include<math.h> #define LL long long #define lson rt<<1 #define rson rt<<1|1 using namespace std; const LL maxn = 100005; LL as[maxn<<2],bs[maxn<<2]; LL cs[maxn],n,m,cas; inline void pushUp(LL rt){ as[rt] = as[lson] + as[rson]; bs[rt] = max(bs[lson],bs[rson]); } void build(LL rt,LL l,LL r) { LL md = (l + r) >> 1; if(l==r){ as[rt]=cs[l]; bs[rt]=cs[l]; return; } build(lson,l,md); build(rson,md+1,r); pushUp(rt); } LL query(LL rt,LL l,LL r,LL L,LL R) { LL md = (l + r) >> 1; if(L<=l && r<=R)return as[rt]; if(R<=md)return query(lson,l,md,L,R); if(L>md)return query(rson,md+1,r,L,R); return query(lson,l,md,L,md)+query(rson,md+1,r,md+1,R); } void update(LL rt,LL l,LL r,LL L,LL R) { LL md = (l + r) >> 1; if(bs[rt]==1)return; if(l==r){ as[rt]=bs[rt]=sqrt(as[rt]+0.0); return; } if(R<=md)update(lson,l,md,L,R); else if(L>md)update(rson,md+1,r,L,R); else update(lson,l,md,L,md),update(rson,md+1,r,md+1,R); pushUp(rt); } inline LL scan(){ LL res=0,ch; while(!((ch=getchar())>='0' && ch<='9')) if(ch==EOF) return 1<<30; res=ch-'0'; while((ch=getchar())>='0' && ch<='9') res=res*10+(ch-'0'); return res; } int main() { while(scanf("%lld",&n)==1){ for(LL i = 1; i <= n; ++ i) cs[i]=scan(); build(1,1,n); scanf("%lld",&m); printf("Case #%lld:\n",++cas); while(m--){ LL o,l,r; o=scan();l=scan();r=scan(); if(l>r)l^=r^=l^=r; if(o)printf("%lld\n",query(1,1,n,l,r)); else update(1,1,n,l,r); } puts(""); } return 0; }

浙公网安备 33010602011771号