poj 3468 A Simple Problem with Integers 数据结构

线段树水题

写splay练手

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 using namespace std;
  6 #define MAXN 100000+100
  7 struct node
  8 {
  9     long long sum,father,left,right,adt,cnt,num;
 10 };
 11 node tree[MAXN];
 12 int top=0,n,m,root;
 13 long long a[MAXN];
 14 void update(int x)
 15 {
 16     tree[x].sum=tree[tree[x].left].sum+tree[tree[x].right].sum+tree[x].num;
 17     tree[x].cnt=tree[tree[x].left].cnt+tree[tree[x].right].cnt+1;
 18 }
 19 void push_down(int x)
 20 {
 21     tree[tree[x].left].adt+=tree[x].adt;
 22     tree[tree[x].left].num+=tree[x].adt;
 23     tree[tree[x].left].sum+=tree[x].adt*tree[tree[x].left].cnt;
 24     tree[tree[x].right].adt+=tree[x].adt;
 25     tree[tree[x].right].sum+=tree[x].adt*tree[tree[x].right].cnt;
 26     tree[tree[x].right].num+=tree[x].adt;
 27     tree[x].adt=0;
 28 }
 29 
 30 void left_rotate(int x)
 31 {
 32     int y=tree[x].father,z=tree[x].left;
 33     if(y==tree[tree[y].father].left) tree[tree[y].father].left=x;
 34     else tree[tree[y].father].right=x;
 35     tree[x].father=tree[y].father;
 36     tree[x].left=y;
 37     tree[y].right=z;
 38     tree[y].father=x;
 39     tree[z].father=y;
 40     update(y); update(x);
 41 }
 42 
 43 void right_rotate(int x)
 44 {
 45     int y=tree[x].father,z=tree[x].right;
 46     if(y==tree[tree[y].father].right) tree[tree[y].father].right=x;
 47     else tree[tree[y].father].left=x;
 48     tree[x].father=tree[y].father;
 49     tree[x].right=y;
 50     tree[y].left=z;
 51     tree[y].father=x;
 52     tree[z].father=y;
 53     update(y); update(x);
 54 }
 55 
 56 void splay(int rootnew,int x)
 57 {
 58     push_down(x);
 59     int fa=tree[rootnew].father;
 60     while(tree[x].father!=fa)
 61     {
 62         int y=tree[x].father;
 63         int z=tree[y].father;
 64         if(z==fa)
 65         {
 66             if(x==tree[y].left) right_rotate(x);
 67             else left_rotate(x);
 68             break;
 69         }
 70         if(y==tree[z].left)
 71             if(x==tree[y].left) right_rotate(y),right_rotate(x);
 72             else left_rotate(x),right_rotate(x);
 73         else
 74             if(x==tree[y].left) right_rotate(x),left_rotate(x);
 75             else left_rotate(y),left_rotate(x);
 76     }
 77     if(rootnew==root) 
 78         root=x;
 79 }
 80 int newnode(int lnum,int rnum,int value)
 81 {
 82     tree[++top].left=lnum; tree[top].right=rnum;
 83     tree[lnum].father=tree[rnum].father=top;
 84     tree[top].num=value;
 85     update(top);
 86     return top;
 87 }
 88 int build_tree(int l,int r)
 89 {
 90     if(l>r) return 0;
 91     int mid=(l+r)/2;
 92     int lnum=build_tree(l,mid-1);
 93     int rnum=build_tree(mid+1,r);
 94     return newnode(lnum,rnum,a[mid]);
 95 }
 96 void find(int root,int pos)
 97 {
 98     int x=root;
 99     while(push_down(x),tree[tree[x].left].cnt+1!=pos)
100     {
101         if(pos<=tree[tree[x].left].cnt)
102             x=tree[x].left;
103         else
104             pos-=tree[tree[x].left].cnt+1, x=tree[x].right;
105     }
106     splay(root,x);
107 }
108 void query(int x,int y)
109 {
110     find(root,x-1);        
111     find(tree[root].right,y-x+2);
112     printf("%lld\n",(tree+tree[tree[root].right].left)->sum);
113 }
114 void add(int x,int y,long long z)
115 {
116     find(root,x-1);
117     find(tree[root].right,y-x+2);
118     int p=tree[tree[root].right].left;
119     tree[p].sum+=z*tree[p].cnt;
120     tree[p].adt+=z;
121     tree[p].num+=z;
122 }
123 
124 int main()
125 {
126     int i,j;
127     char c[10];
128     memset(tree,0,sizeof(tree));
129     memset(a,0,sizeof(a));
130     scanf("%d%d",&n,&m);
131     for(i=2;i<=n+1;i++)
132         scanf("%lld",a+i);
133     root=build_tree(1,n+2);
134     int x,y;
135     long long z;
136     for(i=1;i<=m;i++)
137     {
138         scanf("%s",c);
139         if(c[0]=='Q')
140         {
141             scanf("%d%d",&x,&y);
142             query(x+1,y+1);
143         }
144         else
145         {
146             scanf("%d%d%lld",&x,&y,&z);
147             add(x+1,y+1,z);
148         }
149     }
150     return 0;
151 }
152             
原文地址:https://www.cnblogs.com/myoi/p/2513961.html