线段树(树状数组)hdu4267
来源:互联网 发布:金手指炒股软件 编辑:程序博客网 时间:2024/06/05 22:43
Online JudgeOnline ExerciseOnline TeachingOnline ContestsExercise AuthorF.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsBest Coder beta
VIP | STD Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
***重磅消息——[BestCoder Round #4]冠军将获得iPad Mini一部!
《BestCoder用户手册》下载
Total Submission(s): 3544 Accepted Submission(s): 1094
线段树代码(别人的):
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsBest Coder beta
VIP | STD Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
lee
Mail 0(0)
Control Panel
Sign Out
Mail 0(0)
Control Panel
Sign Out
***重磅消息——[BestCoder Round #4]冠军将获得iPad Mini一部!
《BestCoder用户手册》下载
A Simple Problem with Integers
Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3544 Accepted Submission(s): 1094
Problem Description
Let A1, A2, ... , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. The other is to query the value of some element.
Input
There are a lot of test cases.
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, ... , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
"1 a b k c" means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
"2 a" means querying the value of Aa. (1 <= a <= N)
The first line contains an integer N. (1 <= N <= 50000)
The second line contains N numbers which are the initial values of A1, A2, ... , AN. (-10,000,000 <= the initial value of Ai <= 10,000,000)
The third line contains an integer Q. (1 <= Q <= 50000)
Each of the following Q lines represents an operation.
"1 a b k c" means adding c to each of Ai which satisfies a <= i <= b and (i - a) % k == 0. (1 <= a <= b <= N, 1 <= k <= 10, -1,000 <= c <= 1,000)
"2 a" means querying the value of Aa. (1 <= a <= N)
Output
For each test case, output several lines to answer all query operations.
Sample Input
4 1 1 1 1142 12 22 32 41 2 3 1 22 1 2 22 32 41 1 4 2 12 12 22 32 4
Sample Output
111113312341
又是一道神奇的题目。。。
这个题是对区间内不同的数加上一个值,但线段树只能维护连续的区间,所以这里我们按照k进行分组,根据(i-a)%k==0 --> i%k=a%k。
分组后一共有55中情况:
1,2,3,4,5......
1,3,5,7,9......
2,4,6,8,10....
1,4,7,10,13...
2,5,9,12,15...
3,6,10,13,16...
这样输入a,b,就可以定位到tree[k][a%k]这一组,然后对组内进行成段更新,线段树和树状数组都可以。
Tips:
树状数组的优势是方便动态求值和更新..
可惜树状数组是单点更新
倒是有个方法可以快速成段更新
就是在区间[a, b]内更新+x就在a的位置+x 然后在b+1的位置-x
求某点a的值就是求数组中1~a的和..
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=50010;int n,a[maxn];struct BIT{ int val[maxn]; void clear(){memset(val,0,sizeof(val));} int lowbit(int x) { return x&(-x); } void update(int s,int e,int x) { while(e>0) { val[e]+=x; e-=lowbit(e); } s--; while(s>0) { val[s]-=x; s-=lowbit(s); } } int getsum(int x) { int sum=0; while(x<maxn) { sum+=val[x]; x+=lowbit(x); } return sum; }}tree[12][12];int main(){ while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=0;i<=10;i++) for(int j=0;j<=10;j++)tree[i][j].clear(); int q; scanf("%d",&q); while(q--) { int op,l,r,k,x; scanf("%d",&op); if(op==1) { scanf("%d%d%d%d",&l,&r,&k,&x); tree[k][l%k].update(l/k+1,l/k+(r-l)/k+1,x); } else { scanf("%d",&x); int sum=0; for(int i=1;i<=10;i++) sum+=tree[i][x%i].getsum(x/i+1); printf("%d\n",sum+a[x]); } } } return 0;}
线段树代码(别人的):
#include<algorithm>#include<cstdio>#include<string.h>#include<vector>using namespace std;const int N=50010;int sum[N<<2][55];int col[N<<2],res[N];#define lson l,mid, rt << 1#define rson mid+1,r,rt << 1 | 1int mod,LL;int shunxu[11][11];void PushDown(int rt){ if(col[rt]) { col[rt<<1] += col[rt]; col[rt<<1|1] += col[rt]; col[rt]=0; for(int i=0; i<55; i++) { sum[rt<<1][i] += sum[rt][i]; sum[rt<<1|1][i] += sum[rt][i] ; sum[rt][i]=0; } }}void build(int l,int r,int rt){ col[rt]=0; memset(sum[rt],0,sizeof(sum[rt])); if(l==r) return; int mid=(l+r)>>1; build(lson); build(rson);}void update(int L,int R,int val,int l,int r,int rt){ if(l==L&&r==R) { col[rt]+=val; sum[rt][shunxu[mod][LL%mod]]+=val; return ; } PushDown(rt); int mid=(l+r)>>1; if(R<=mid)update(L,R,val,lson); else if(L>mid)update(L,R,val,rson); else { update(L,mid,val,lson); update(mid+1,R,val,rson); }}int query(int l,int r,int rt,int m){ if(l==r) { int d=0; for(int i=1; i<=10; i++) d += sum[rt][shunxu[i][m%i]]; return d+res[l]; } int mid=(l+r)>>1; PushDown(rt); if(m<=mid) return query(lson,m); else return query(rson,m);}int main(){ int n,q,cc=0; for(int i=1; i<=10; i++) for(int j=0; j<i; j++) shunxu[i][j]=cc++; while(~scanf("%d",&n)) { build(1,n,1); int q; for(int i=1; i<=n; i++) scanf("%d",&res[i]); scanf("%d",&q); int kk,aa,RR,k,val; while(q--) { scanf("%d",&kk); if(kk==2) { scanf("%d",&aa); printf("%d\n",query(1,n,1,aa)); } else if(kk==1) { scanf("%d%d%d%d",&LL,&RR,&mod,&val); update(LL,RR,val,1,n,1); } } } return 0;}
0 0
- 线段树(树状数组)hdu4267
- hdu4267(树状数组,有规则区间修改)
- HDU4267(树状数组)
- hdu4267——树状数组
- HDU4267 分组线段树
- hdu4267 线段树
- hdu4267分组线段树
- hdu4267--A Simple Problem with Integers(树状数组)
- hdu4267 线段树单点更新
- 线段树,树状数组
- 线段树,树状数组
- 线段树,树状数组
- 线段树,树状数组
- 树状数组-线段树
- 线段树 && 树状数组
- 线段树,树状数组
- 线段树&&树状数组
- 线段树+树状数组
- url 编码(percentcode 百分号编码)
- sprintf和sscanf
- 交叉工具链安装
- 杭电 2147
- NameNode跟secondarynamenode的执行过程
- 线段树(树状数组)hdu4267
- 奇异值分解
- CONFIG_IKCONFIG_PROC=y
- hdu 1247 Hat’s Words 字典树
- Cygwin编译自定义OpenCV库报错:opencv_contrib: LOCAL_SRC_FILES points to a missing file
- Android 开发尝试总结二:Android版HelloWorld项目文件结构分析
- 创建基于wicket的web项目(二)-常用控件
- UVA - 10474 Where is the Marble?
- (六)8天快速掌握Android视频教程_电话拨号器