线段树模板

Codevs_1082_线段树练习3

 http://codevs.cn/problem/1082/

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 const int maxn=200005;
 6 typedef long long ll;
 7 int n,q;
 8 int w[maxn];
 9 struct node { int l,r; ll x,d; }a[3*maxn];
10 
11 void build_tree(int l,int r,int k)
12 {
13     a[k].l=l; a[k].r=r; a[k].d=0;
14     if(l==r) { a[k].x=w[l]; return; }
15     int mid=l+(r-l)/2;
16     build_tree(l,mid,2*k);
17     build_tree(mid+1,r,2*k+1);
18     a[k].x=a[2*k].x+a[2*k+1].x;
19 }
20 
21 void update(int l,int r,int k,int x)
22 {
23     if(a[k].l==l&&a[k].r==r)
24     {
25         a[k].x+=(r-l+1)*x;
26         a[k].d+=x;
27         return;
28     }
29     
30     if(a[k].d)
31     {
32         a[2*k].x+=(a[2*k].r-a[2*k].l+1)*a[k].d;
33         a[2*k+1].x+=(a[2*k+1].r-a[2*k+1].l+1)*a[k].d;
34         a[2*k].d+=a[k].d;
35         a[2*k+1].d+=a[k].d;
36         a[k].d=0;
37     }
38     int mid=a[k].l+(a[k].r-a[k].l)/2;
39     if(r<=mid) update(l,r,2*k,x);
40     else if(l>mid) update(l,r,2*k+1,x);
41     else { update(l,mid,2*k,x); update(mid+1,r,2*k+1,x); }
42     a[k].x=a[2*k].x+a[2*k+1].x;
43 }
44 
45 ll search(int l,int r,int k)
46 {
47     if(a[k].l==l&&a[k].r==r) return a[k].x;
48     if(a[k].d)
49     {
50         a[2*k].x+=(a[2*k].r-a[2*k].l+1)*a[k].d;
51         a[2*k+1].x+=(a[2*k+1].r-a[2*k+1].l+1)*a[k].d;
52         a[2*k].d+=a[k].d;
53         a[2*k+1].d+=a[k].d;
54         a[k].d=0;
55     }
56     int mid=a[k].l+(a[k].r-a[k].l)/2;
57     if(r<=mid) return search(l,r,2*k);
58     else if(l>mid) return search(l,r,2*k+1);
59     else return search(l,mid,2*k)+search(mid+1,r,2*k+1);
60 }
61 
62 int main()
63 {
64     scanf("%d",&n);
65     for(int i=1;i<=n;i++) scanf("%d",&w[i]);
66     
67     build_tree(1,n,1);
68     scanf("%d",&q);
69     for(int i=1;i<=q;i++)
70     {
71         int qry,l,r,x;
72         scanf("%d%d%d",&qry,&l,&r);
73         switch(qry)
74         {
75             case 1:
76                 scanf("%d",&x);
77                 update(l,r,1,x);
78                 break;
79             case 2:
80                 printf("%lld\n",search(l,r,1));
81                 break;
82         }
83     }
84     return 0;
85 }
View Code

 

posted @ 2016-04-26 16:42  晴歌。  阅读(184)  评论(0编辑  收藏  举报