POJ3468---A Simple Problem with Integers
此题简单的做法自然是 线段树 或树状数组,splay只是为了练手。。依旧 是学习bin神的模板,写了一发之后理解更深了。
1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <ctime> 5 #include <queue> 6 #include <stack> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 typedef unsigned long long ull; 16 typedef long long ll; 17 const int inf = 0x3f3f3f3f; 18 const double eps = 1e-8; 19 const int maxn = 1e5+100; 20 ll add[maxn],sum[maxn]; 21 int ch[maxn][2],siz[maxn],key[maxn],a[maxn]; 22 int pre[maxn]; 23 int tot1,root; 24 void new_node(int &r,int father,int k) 25 { 26 r = ++tot1; 27 pre[r] = father; 28 siz[r] = 1; 29 add[r] = 0; 30 key[r] = k; 31 sum[r] = k; 32 ch[r][0] = ch[r][1] = 0; 33 } 34 35 void update(int r,int val) 36 { 37 if (r == 0) 38 return ; 39 add[r] += val; 40 key[r] += val; 41 sum[r] += (ll)val * siz[r]; 42 } 43 44 void push_down(int x) 45 { 46 if (add[x]) 47 { 48 update(ch[x][0],add[x]); 49 update(ch[x][1],add[x]); 50 add[x] = 0; 51 } 52 } 53 void push_up(int x) 54 { 55 siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1; 56 sum[x] = sum[ch[x][0]] + sum[ch[x][1]] + key[x]; 57 } 58 void build(int &x,int l,int r,int father) 59 { 60 if (l > r) 61 return; 62 int mid = (l + r) >> 1; 63 new_node(x,father,a[mid-1]); 64 build(ch[x][0],l,mid-1,x); 65 build(ch[x][1],mid+1,r,x); 66 push_up(x); 67 } 68 void init(int n) 69 { 70 tot1 = 0; 71 root = 0; 72 new_node(root,0,-1); 73 new_node(ch[root][1],root,-1); 74 for (int i = 0; i < n; i++) 75 scanf ("%d",a+i); 76 build(ch[ch[root][1]][0],1,n,ch[root][1]); 77 push_up(ch[root][1]); 78 push_up(root); 79 } 80 void Rotate(int x,int kind) 81 { 82 int y = pre[x]; 83 push_down(y); 84 push_down(x); // 标记下传 85 86 ch[y][!kind] = ch[x][kind]; 87 pre[ch[x][kind]] = y; 88 ch[x][kind] = y; 89 if (pre[y]) 90 ch[pre[y]][ch[pre[y]][1] == y] = x; 91 pre[x] = pre[y]; 92 pre[y] = x; 93 push_up(y); // ??? 94 } 95 void Splay(int r,int goal) 96 { 97 push_down(r); 98 while (pre[r] != goal) 99 { 100 if (pre[pre[r]] == goal) 101 Rotate(r,ch[pre[r]][0] == r); 102 else 103 { 104 int y = pre[r]; 105 int kind = (ch[pre[y]][0] == y); 106 if (ch[y][kind] == r) 107 { 108 Rotate(r,!kind); 109 Rotate(r,kind); 110 } 111 else 112 { 113 Rotate(y,kind); 114 Rotate(r,kind); 115 } 116 } 117 } 118 push_up(r); 119 if (goal == 0) 120 root = r; 121 } 122 int Get_kth(int r,int k) 123 { 124 push_down(r); 125 int t = siz[ch[r][0]] + 1; 126 if (k == t) 127 return r; 128 if (t > k) 129 Get_kth(ch[r][0],k); 130 else 131 Get_kth(ch[r][1],k-t); 132 } 133 void ADD(int l,int r,int val) 134 { 135 Splay(Get_kth(root,l),0); 136 Splay(Get_kth(root,r+2),root); 137 update(ch[ch[root][1]][0],val); 138 push_up(ch[root][1]); 139 push_up(root); 140 } 141 ll query(int l,int r) 142 { 143 Splay(Get_kth(root,l),0); 144 Splay(Get_kth(root,r+2),root); 145 return sum[ch[ch[root][1]][0]]; 146 } 147 int main(void) 148 { 149 #ifndef ONLINE_JUDGE 150 freopen("in.txt","r",stdin); 151 #endif 152 int n,q; 153 while (~scanf ("%d%d",&n,&q)) 154 { 155 init(n); 156 char op[8]; 157 while (q--) 158 { 159 scanf ("%s",op); 160 if (op[0] == 'C') 161 { 162 int x,y,v; 163 scanf ("%d%d%d",&x,&y,&v); 164 ADD(x,y,v); 165 } 166 if (op[0] == 'Q') 167 { 168 int x,y; 169 scanf ("%d%d",&x,&y); 170 printf("%lld\n",query(x,y)); 171 } 172 } 173 } 174 return 0; 175 }