首页 > 代码库 > poj3468
poj3468
线段树中对一段区间操作的方法----记录增量。详细实现见代码。
还要好好体会!
1 //Accepted 6688K 1485MS 2 #include <cstdio> 3 #include <cstring> 4 #define imax 100005 5 struct node 6 { 7 int l,r; 8 __int64 add,sum; 9 }f[imax*3]; 10 int num[imax]; 11 int n,m; 12 void build(int t,int l,int r) 13 { 14 f[t].l=l; 15 f[t].r=r; 16 f[t].add=0; 17 if (l==r) 18 { 19 f[t].sum=num[l]; 20 return ; 21 } 22 int mid=(l+r)/2; 23 build(2*t,l,mid); 24 build(2*t+1,mid+1,r); 25 f[t].sum=f[2*t].sum+f[2*t+1].sum; 26 } 27 void Add(int t,int l,int r,int c) 28 { 29 if (f[t].l==l && f[t].r==r) 30 { 31 f[t].add+=c; 32 return ; 33 } 34 f[t].sum+=c*(r-l+1); 35 int mid=(f[t].l+f[t].r)/2; 36 if (r<=mid) Add(2*t,l,r,c); 37 else 38 { 39 if (l>mid) Add(2*t+1,l,r,c); 40 else 41 { 42 Add(2*t,l,mid,c); 43 Add(2*t+1,mid+1,r,c); 44 } 45 } 46 } 47 __int64 query(int t,int l,int r) 48 { 49 if (f[t].l==l && f[t].r==r) 50 { 51 return f[t].sum+f[t].add*(f[t].r-f[t].l+1); 52 } 53 int mid=(f[t].l+f[t].r)/2; 54 f[2*t].add+=f[t].add; 55 f[2*t+1].add+=f[t].add; 56 f[t].sum+=f[t].add*(f[t].r-f[t].l+1); 57 f[t].add=0; 58 if (r<=mid) return query(2*t,l,r); 59 else 60 { 61 if (l>mid) return query(2*t+1,l,r); 62 else 63 return query(2*t,l,mid)+query(2*t+1,mid+1,r); 64 } 65 } 66 int main() 67 { 68 while (scanf("%d%d",&n,&m)!=EOF) 69 { 70 for (int i=1;i<=n;i++) 71 scanf("%d",&num[i]); 72 build(1,1,n); 73 int x,y,c; 74 char ch[5]; 75 for (int i=0;i<m;i++) 76 { 77 scanf("%s",ch); 78 if (ch[0]==‘Q‘) 79 { 80 scanf("%d%d",&x,&y); 81 printf("%I64d\n",query(1,x,y)); 82 } 83 else 84 { 85 scanf("%d%d%d",&x,&y,&c); 86 Add(1,x,y,c); 87 } 88 } 89 } 90 return 0; 91 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。