题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest
The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest
比赛的时候知道必须成段更新但是没有想到怎么更新,于是就单点更新了,果断TLE,其实只要知道__int64 范围内的数最多取8次跟下就能到1或0,这样就有思路了,就是预先把每个数的i次根下都求出来,在建树的过程中直接把和更新上去,这样每次更新只需要更新取根次数就可以了。
代码如下:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int maxx=100002; struct Tree { __int64 sum[9]; int cnt; int col; }; __int64 da[maxx],mx; int lim; Tree tree[maxx<<2]; void pushUp(int rt) { for (int i=0;i<=lim;i++) { tree[rt].sum[i]=tree[rt<<1].sum[i]+tree[rt<<1|1].sum[i]; } } void pushDown(int rt) { if (tree[rt].col!=0) { tree[rt<<1].cnt+=tree[rt].col; tree[rt<<1].col+=tree[rt].col; tree[rt<<1|1].cnt+=tree[rt].col; tree[rt<<1|1].col+=tree[rt].col; tree[rt].col=0; } } void update(int L,int R,int l,int r,int rt) { if (L<=l && r<=R) { tree[rt].col+=1; tree[rt].cnt+=1; return; } pushDown(rt); int m=(l+r)>>1; if (L<=m)update(L,R,lson); if (R>m)update(L,R,rson); } void build(int l,int r,int rt) { tree[rt].cnt=tree[rt].col=0; if (l==r) { tree[rt].sum[0]=da[l]; for (int i=1;i<=lim;i++) { tree[rt].sum[i]=(__int64)sqrt((double)tree[rt].sum[i-1]); } return; } int m=(l+r)>>1; build(lson); build(rson); pushUp(rt); } __int64 query(int L,int R,int l,int r,int rt) { if (L<=l && r<=R) { if (tree[rt].cnt>lim)tree[rt].cnt=lim; if (tree[rt].cnt==lim || l==r) { return tree[rt].sum[tree[rt].cnt]; } pushDown(rt); int m=(l+r)>>1; return query(L,R,lson)+query(L,R,rson); } pushDown(rt); int m=(l+r)>>1; __int64 ret=0; if (L<=m) ret+=query(L,R,lson); if (R>m) ret+=query(L,R,rson); return ret; } int main() { int n,o,cas=1; while (scanf("%d",&n)!=EOF) { mx=0; int i; printf("Case #%d:\n",cas++); for (i=1;i<=n;i++) { scanf("%I64d",&da[i]); if (mx<da[i])mx=da[i]; } for (lim=1;mx>1;mx=(__int64)sqrt((double)mx),lim++); build(1,n,1); scanf("%d",&o); for (i=1;i<=o;i++) { int x,y,mark; scanf("%d%d%d",&mark,&x,&y); if (x>y)swap(x,y); if (mark==0) { update(x,y,1,n,1); } else { printf("%I64d\n",query(x,y,1,n,1)); } } printf("\n"); } return 0; }
The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest
The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest
The 36th ACM/ICPC Asia Regional Shanghai Site —— Online Contest