树状数组解决区间求和问题(模板)
2017-11-20 20:10
441 查看
1.改点求段模型
题目:HDU 1166 敌兵布阵
2.改段求段模型
题目:POJ 3468 A Simple Problem with Integers
3.改点求区间最大值
题目:HDU 1754 I Hate It
题目:HDU 1166 敌兵布阵
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXL=50000; int tree[MAXL+50]; int a[MAXL+50]; char s[10]; int n; int lowbit(int k) { return k&-k; } void update(int i,int value,int t) { value*=t; while(i<=n) { tree[i]+=value; i+=lowbit(i); } } int getsum(int i) { int ans=0; while(i>0) { ans+=tree[i]; i-=lowbit(i); } return ans; } int main() { int T; int CASE=1; scanf("%d",&T); while(T--) { memset(tree,0,sizeof(tree)); scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",a+i); update(i,a[i],1); } int x,y; cout<<"Case "<<CASE++<<":"<<endl; while(scanf("%s",s)) { if(!strcmp(s,"End")) break; else if(!strcmp(s,"Add")) { scanf("%d%d",&x,&y); update(x,y,1); } else if(!strcmp(s,"Sub")) { scanf("%d%d",&x,&y); update(x,y,-1); } else { scanf("%d%d",&x,&y); int ans1=getsum(y); int ans2=getsum(x-1); cout<<ans1-ans2<<endl; } } } }
2.改段求段模型
题目:POJ 3468 A Simple Problem with Integers
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXL=100000; typedef long long int LL; LL b[MAXL+50],c[MAXL+50]; LL sum[MAXL+50]; int a[MAXL+50]; int n,m; int lowbit(int k) { return k&-k; } void update(LL a[],int i,int value) { while(i<=n) { a[i]+=value; i+=lowbit(i); } } LL getsum(LL a[],int i) { LL ans=0; while(i>0) { ans+=a[i]; i-=lowbit(i); } return ans; } int main() { memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); memset(sum,0,sizeof(sum)); scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) scanf("%d",a+i); for(int i=0;i<=n;i++) sum[i]=sum[i-1]+a[i]; int x,y,value; char ch; int T=m; while(T--) { getchar(); scanf("%c",&ch); if(ch=='C') { scanf("%d%d%d",&x,&y,&value); update(b,x,value); update(b,y+1,-value); update(c,x,value*x); update(c,y+1,-value*(y+1)); } else if(ch=='Q') { scanf("%d%d",&x,&y); LL ans=0; ans=sum[y]-sum[x-1]; ans+=(y+1)*getsum(b,y)-getsum(c,y); ans-=(x*getsum(b,x-1))-getsum(c,x-1); cout<<ans<<endl; } } }
3.改点求区间最大值
题目:HDU 1754 I Hate It
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXL(200000); int tree[MAXL+50]; int a[MAXL+50]; int n,m; int max(int a,int b) { return a>b?a:b; } int lowbit(int k) { return k&(-k); } void init() { for(int i=1; i<=n; i++) { tree[i]=a[i]; for(int j=1; j<lowbit(i); j<<=1) tree[i]=max(tree[i],tree[i-j]); } } void Update(int x) { for(int i=x; i<=n; i+=lowbit(i)) { tree[i]=a[i]; for(int j=1; j<lowbit(i); j<<=1) tree[i]=max(tree[i],tree[i-j]); } } int Query(int x,int y) { int ans=0; while(x<=y) { ans=max(a[y],ans); for(y--; y-lowbit(y)>=x; y-=lowbit(y)) ans=max(tree[y],ans); } return ans; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=1; i<=n; i++) scanf("%d",a+i); init(); char ch; int x,y; int T=m; while(T--) { scanf("%c",&ch); if(ch=='U') { scanf("%d%d",&x,&y); a[x]=y; Update(x); } if(ch=='Q') { scanf("%d%d",&x,&y); int ans=Query(x,y); printf("%d\n",ans); } } } }
相关文章推荐
- 用树状数组解决"区间和"问题模板(1166)
- 用树状数组解决区间查询问题
- 树状数组关于区间修改区间求和的问题
- 用树状数组解决求区间最值的问题:hdu1754
- 用树状数组解决区间查询问题
- P3374 【模板】树状数组 1(单点增减,区间求和)
- 【模板】树状数组 区间修改,区间求和 (模板题:洛谷P3368树状数组2)
- scu 2057 树状数组 单点更新区间求和问题
- poj 3468 树状数组解法(解决区间更新,区间求和)
- 【模板】树状数组 单点修改,区间求和 (模板题:洛谷P3374树状数组1)
- 二维树状数组 区间求和模板(#1336 : Matrix Sum)
- poj 3468 树状数组解法(解决区间更新,区间求和)
- 【模板】树状数组 区间修改,区间求和 (模板题:洛谷P3372线段树1)
- poj 3468 树状数组解法(解决区间更新,区间求和)
- 用树状数组解决区间查询问题
- 用树状数组解决区间查询问题
- 树链剖分&树状数组区间加减区间求和模板
- 模板(线段树 + 树状数组 + 单点查询 + 区间查询)eg:HDU 1754 - I Hate It
- 区间查询(树状数组之差点问线问题)
- cf Babaei and Birthday Cake(树状数组解决LIS问题)