【XSY2111】Chef and Churus 分块 树状数组
2017-09-18 19:54
369 查看
题目描述
有一个长度为n的数组A和n个区间[li,ri],有q次操作:1 x y:把ax改成y
2 x y:求第l个区间到第r个区间的区间和的和。
n,q≤105,ai≤109
题解
分块。设si为第i块的所有区间的区间和,di,j为第i块有多少个区间包含了j这个位置。
修改时修改树状数组和每个区间的区间和。设当前ax=v,则si+=(y−v)×di,x
查询时完整的区间直接查询区间和,不完整的区间就暴力查询。
设块大小为m,时间复杂度为
T(n)=O(nm+mlogn)
当m=nlogn−−−√时
T(n)min=O(nnlogn−−−−−√)
代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<ctime> #include<utility> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; ull c[100010]; int a[100010]; int n; void add(int x,ull v) { for(;x<=n;x+=x&-x) c[x]+=v; } ull sum(int x) { ull s=0; for(;x;x-=x&-x) s+=c[x]; return s; } int bl; ull s[1010]; int d[1010][100010]; int l[100010]; int r[100010]; int block[100010]; int left[100010]; int right[100010]; int main() { memset(c,0,sizeof c); // freopen("xsy2111.in","r",stdin); // freopen("xsy2111.out","w",stdout); int m; scanf("%d",&n); int i; for(i=1;i<=n;i++) { scanf("%d",&a[i]); add(i,a[i]); } bl=100; m=(n+bl-1)/bl; for(i=1;i<=n;i++) block[i]=(i+bl-1)/bl; for(i=1;i<=m;i++) { left[i]=(i-1)*bl+1; right[i]=min(i*bl,n); } for(i=1;i<=n;i++) { scanf("%d%d",&l[i],&r[i]); s[block[i]]+=sum(r[i])-sum(l[i]-1); d[block[i]][l[i]]++; if(r[i]<n) d[block[i]][r[i]+1]--; } int j; for(i=1;i<=m;i++) for(j=2;j<=n;j++) d[i][j]+=d[i][j-1]; int q; scanf("%d",&q); int op,x,y,k; for(i=1;i<=q;i++) { scanf("%d%d%d",&op,&x,&y); if(op==1) { int v=a[x]; for(j=1;j<=m;j++) s[j]+=ull(y-v)*d[j][x]; add(x,y-v); a[x]=y; } else { ull ans=0; for(j=block[x];j<=block[y];j++) if(left[j]>=x&&right[j]<=y) ans+=s[j]; else { int mi=max(left[j],x); int mx=min(right[j],y); for(k=mi;k<=mx;k++) ans+=sum(r[k])-sum(l[k]-1); } printf("%llu\n",ans); } } return 0; }
相关文章推荐
- CodeChef "Chef and Churus" 分块+树状数组
- 【分块+树状数组】codechef November Challenge 2014 .Chef and Churu
- 【CodeChef】Chef and Churu 分块+树状数组
- Hdu1166 敌兵布阵 [分块][树状数组][线段树]
- CF 369E - Valera and Queries(树状数组)
- 【树状数组】[CodeForces - 341D]Iahub and Xors
- Codeforces Round #348 E. Little Artem and Time Machine 树状数组 单点更新
- cf#348-E. Little Artem and Time Machine-树状数组+map节点(动态开点树状数组)
- bzoj2141【分块+树状数组】
- cf703D. Mishka and Interesting sum(树状数组)
- 【BZOJ3289】【莫队分块+树状数组求逆序对】Mato的文件管理
- 【BZOJ3744】Gty的妹子序列-序列分块+树状数组
- Codeforces Round #348 E. Little Artem and Time Machine 树状数组 单点更新
- Codeforces 703D Mishka and Interesting sum (树状数组求区间内不同的数的异或和)
- CF 315B - Sereja and Array(树状数组)
- Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum (树状数组维护异或值) ★ ★
- Codeforces 387E George and Cards【思维+RMQ+二分+树状数组】被卡常= =
- [BZOJ]2141: 排队 分块+树状数组
- 2141: 排队 分块+树状数组
- HDU 5654 xiaoxin and his watermelon candy 离线树状数组