POJ3468 本来是一道线段树
// 然而博主用 Splay Tree 做的,4000+ ms。。。飘过
1 #include "cstdio" 2 using namespace std; 3 long long in[100010]; 4 const int INF = 1 << 28; 5 6 struct Node { 7 Node *pre, *ch[2]; 8 long long sz, val; 9 long long sum, add; 10 } *null, *root, buf[100010]; 11 int idx; 12 13 Node *usdNode[100010]; 14 int top; 15 16 inline void PushDown(Node *p) 17 { 18 if (p == null) { 19 return ; 20 } 21 if(p->add) { 22 p->sum += p->add * p->sz; 23 p->val += p->add; 24 if(p->ch[0] != null) { 25 p->ch[0]->add += p->add; 26 } 27 if(p->ch[1] != null) { 28 p->ch[1]->add += p->add; 29 } 30 p->add = 0; 31 } 32 } 33 34 inline void Update(Node *p) 35 { 36 if (p == null) { 37 return ; 38 } 39 PushDown(p); 40 PushDown(p->ch[0]); 41 PushDown(p->ch[1]); 42 p->sz = p->ch[0]->sz + p->ch[1]->sz + 1; 43 p->sum = p->ch[0]->sum + p->ch[1]->sum + p->val; 44 } 45 46 Node *AddNode(int val) 47 { 48 Node *p; 49 if (top) { 50 p = usdNode[top]; 51 --top; 52 } else { 53 ++idx; 54 p = &buf[idx]; 55 } 56 p->pre = p->ch[0] = p->ch[1] = null; 57 p->sz = 1, p->val = val; 58 59 p->add = 0; 60 p->sum = val; 61 return p; 62 } 63 64 void Init() 65 { 66 idx = top = 0; 67 null = AddNode(-INF); 68 null->sz = 0; 69 null->sum = 0; 70 root = AddNode(-INF); 71 72 root->sum = 0; 73 Node *p; 74 75 p = AddNode(-INF); 76 p->sum = 0; 77 78 root->ch[1] = p; 79 p->pre = root; 80 Update(root->ch[1]); 81 Update(root); 82 } 83 84 void Rotate(Node *p, bool c) 85 { 86 Node *f = p->pre; 87 PushDown(f); 88 PushDown(p); 89 f->ch[!c] = p->ch[c]; 90 if (p->ch[c] != null) { 91 p->ch[c]->pre = f; 92 } 93 p->pre = f->pre; 94 if (f->pre != null) { 95 if (f->pre->ch[0] == f) { 96 f->pre->ch[0] = p; 97 } else { 98 f->pre->ch[1] = p; 99 } 100 } 101 p->ch[c] = f; 102 f->pre = p; 103 if (f == root) { 104 root = p; 105 } 106 Update(f); 107 } 108 109 void Splay(Node *p, Node *tf) 110 { 111 Node *f, *ff; 112 PushDown(p); 113 while (p->pre != tf) { 114 f = p->pre, ff = f->pre; 115 if (ff == tf) { 116 Rotate(p, p->pre->ch[0] == p); 117 } else { 118 if (ff->ch[0] == f) { 119 if (f->ch[0] == p) { 120 Rotate(f, 1); 121 Rotate(p, 1); 122 } else { 123 Rotate(p, 0); 124 Rotate(p, 1); 125 } 126 } else { 127 if (f->ch[1] == p) { 128 Rotate(f, 0); 129 Rotate(p, 0); 130 } else { 131 Rotate(p, 1); 132 Rotate(p, 0); 133 } 134 } 135 } 136 Update(p); 137 } 138 } 139 140 Node *Build(int l, int r) 141 { 142 if (l > r) { 143 return null; 144 } 145 int mid = (l + r) >> 1; 146 Node *p = AddNode(in[mid]); 147 p->ch[0] = Build(l, mid - 1); 148 if (p->ch[0] != null) { 149 p->ch[0]->pre = p; 150 } 151 p->ch[1] = Build(mid + 1, r); 152 if (p->ch[1] != null) { 153 p->ch[1]->pre = p; 154 } 155 Update(p); 156 return p; 157 } 158 159 Node *Select(int kth) 160 { 161 int tmp; 162 Node *p = root; 163 while (1) { 164 PushDown(p); 165 tmp = p->ch[0]->sz; 166 if (tmp + 1 == kth) { 167 break; 168 } 169 if (kth <= tmp) { 170 p = p->ch[0]; 171 } else { 172 kth -= tmp + 1; 173 p = p->ch[1]; 174 } 175 } 176 return p; 177 } 178 179 void SegAdd(int pos, int tot, long long delte) 180 { 181 Splay(Select(pos - 1), null); 182 Splay(Select(pos + tot), root); 183 if (root->ch[1]->ch[0] != null) { 184 root->ch[1]->ch[0]->add += delte; 185 Splay(root->ch[1]->ch[0], null); 186 } 187 } 188 189 void GetSum(int pos, int tot) 190 { 191 Splay(Select(pos - 1), null); 192 Splay(Select(pos + tot), root); 193 printf("%lld\n",root->ch[1]->ch[0]->sum); 194 } 195 196 int N, Q; 197 char cmd[10]; 198 199 int main() 200 { 201 int i; 202 scanf("%d%d", &N, &Q); 203 Init(); 204 for(i = 1; i <= N; ++i) { 205 scanf("%lld", &in[i]); 206 } 207 Node *tRoot = Build(1, N); 208 root->ch[1]->ch[0] = tRoot; 209 tRoot->pre = root->ch[1]; 210 Update(root->ch[1]); 211 Update(root); 212 213 int l, r; 214 long long c; 215 while(Q--) { 216 scanf("%s", cmd); 217 switch(cmd[0]) { 218 case 'Q': 219 scanf("%d%d", &l, &r); 220 GetSum(l + 1, r - l + 1); 221 break; 222 case 'C': 223 scanf("%d%d%lld", &l, &r, &c); 224 SegAdd(l + 1, r - l + 1, c); 225 } 226 } 227 }