标签:des style class code ext width color int html cti htm
主要操作为Splay中插入节点,查找前驱和后继节点。
1: #include <cstdio> 2: #include <iostream> 3: #include <cmath>4: using namespace std;
5: #define MaxL 100005
6: #define INF 0x7ffffff
7: #define keyTree sp[sp[root].child[1]].child[0]
8: 9: struct SplayTreeNode
10: {11: int parent, child[2]; // parent and child[0] left child[1] right
12: int sz, val; // sz 表示当前节点为根的子树总节点个数. val表示当前节点的键值。
13: int lazy; // 延迟标记
14: long long sum; // 以x为根节点的子树的所有的和
15: }; 16: 17: int num[MaxL];
18: struct SpalyTree
19: {20: SplayTreeNode sp[MaxL]; // save space
21: int gc[MaxL]; // Garbage Collection idx
22: int root; // root idx
23: int idx; // Forward allocate tree
24: int idxrev; // garbage allocated nodes used for next allocation priority
25: 26: /*
27: A B
28: / \ R(B,RR)-> / \
29: B C <-R(A,LL) D A
30: / \ / \
31: D E E C
32: */
33: void Rotate(int x,int f) // f ==0 l rot,1 r rot
34: {35: int y = sp[x].parent;
36: PushDown(y); 37: PushDown(x); 38: sp[y].child[!f] = sp[x].child[f]; 39: sp[sp[x].child[f]].parent = y; 40: sp[x].parent = sp[y].parent;41: if(sp[x].parent)
42: sp[sp[y].parent].child[ sp[sp[y].parent].child[1] == y]= x; 43: sp[x].child[f] = y; 44: sp[y].parent = x; 45: PushUp(y); 46: } 47: 48: // x to be the child of goal, x and goal are key
49: void Splay(int x, int goal)
50: { 51: PushDown(x);52: while(sp[x].parent != goal)
53: {54: if(sp[sp[x].parent].parent == goal)
55: Rotate(x, sp[sp[x].parent].child[0] == x);56: else
57: {58: int y = sp[x].parent, z = sp[y].parent;
59: int f = sp[z].child[0] == y;
60: if(sp[y].child[f] == x)
61: Rotate(x,!f), Rotate(x,f);62: else
63: Rotate(y,f), Rotate(x,f); 64: } 65: } 66: PushUp(x);67: if(goal == 0) root = x;
68: } 69: 70: // 把第k个的数转到goal下边,一般用来调整区间, 返回其key 键
71: int RotateTo(int k, int goal)
72: {73: int x = root;
74: PushDown(x);75: while(sp[sp[x].child[0]].sz !=k)
76: {77: if( k< sp [ sp[x].child[0] ].sz)
78: x = sp[x].child[0];79: else
80: { 81: k -= sp[sp[x].child[0]].sz +1; 82: x = sp[x].child[1]; 83: } 84: PushDown(x); 85: }86: cout<<"Rotate "<<x<<" goal "<<goal<<endl;
87: Splay(x, goal);88: return x;
89: } 90: 91: // insert a value, return the key
92: // first find the key, then insert a value.
93: // 不重复插入
94: pair<int,bool> Insert(int val)
95: {96: int p = root;
97: while( sp[p].val == val || sp[p].child[ sp[p].val < val ])
98: {99: if(sp[p].val == val)
100: { 101: Splay(p, 0);102: return make_pair(p,false);
103: } 104: p = sp[p].child[sp[p].val < val]; 105: }106: int x = NewNode(sp[p].child[sp[p].val < val], val);
107: sp[x].parent = p; 108: Splay(x, 0);109: return make_pair(x, true);
110: } 111: 112: int findPrefix(int x)
113: { 114: Splay(x,0);115: int p = sp[x].child[0];
116: if(p)
117: {118: while(sp[p].child[1])
119: p = sp[p].child[1]; 120: }121: return p;
122: } 123: 124: int findSuffix(int x)
125: { 126: Splay(x, 0);127: int p = sp[x].child[1];
128: if(p)
129: {130: while(sp[p].child[0])
131: p = sp[p].child[0]; 132: }133: return p;
134: } 135: 136: 137: int NewNode(int &x, int c)
138: {139: if( idxrev) x = gc[--idxrev];
140: else x = ++idx;
141: sp[x].child[1] = 0, sp[x].child[0] = 0, sp[x].parent = 0; 142: sp[x].sz = 1; 143: sp[x].val = sp[x].sum = c; 144: sp[x].lazy = 0;145: return x;
146: } 147: 148: //把以x为祖先结点(x 也算)删掉放进内存池,回收内存
149: void eraseSubTree(int x)
150: {151: int father = sp[x].parent;
152: int head = idxrev , tail = idxrev;
153: for (gc[tail++] = x ; head < tail ; head ++)
154: { 155: idxrev++;156: if( sp[gc[head]].child[0]) gc[tail++] = sp[gc[head]].child[0];
157: if( sp[gc[head]].child[1]) gc[tail++] = sp[gc[head]].child[1];
158: } 159: sp[father].child[ sp[father].child[1] == x] = 0; 160: PushUp(father); 161: } 162: 163: void makeTree(int &x, int l, int r, int parent)
164: {165: if(l > r) return ;
166: int m = (l+r)>>1;
167: NewNode(x,num[m]); 168: makeTree(sp[x].child[0], l, m-1, x); 169: makeTree(sp[x].child[1], m+1, r, x); 170: sp[x].parent = parent; 171: PushUp(x); 172: }173: void Init(int n)
174: { 175: idx = idxrev = 0; 176: root = 0; 177: sp[0].child[0] = sp[0].child[1] = sp[0].parent = 0; 178: sp[0].sz = sp[0].lazy = sp[0].sum = 0; 179: } 180: 181: void Travel(int x)
182: {183: if(x)
184: { 185: Travel( sp[x].child[0]);186: printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x, sp[x].child[0],sp[x].child[1],sp[x].parent,sp[x].sz,sp[x].val);
187: Travel( sp[x].child[1]); 188: } 189: } 190: 191: //Problem Specific Function
192: void PushUp(int x )
193: { 194: sp[x].sz = 1 + sp[sp[x].child[0]].sz + sp[sp[x].child[1]].sz; 195: sp[x].sum = sp[x].lazy + sp[x].val + sp[sp[x].child[0]].sum + sp[sp[x].child[1]].sum; 196: } 197: 198: void PushDown(int x)
199: {200: if(sp[x].lazy)
201: { 202: sp[x].val += sp[x].lazy; 203: sp[sp[x].child[0]].lazy += sp[x].lazy; 204: sp[sp[x].child[1]].lazy += sp[x].lazy;205: sp[sp[x].child[0]].sum += (long long) sp[ sp[x].child[0]].sz * sp[x].lazy;
206: sp[sp[x].child[1]].sum += (long long) sp[ sp[x].child[1]].sz * sp[x].lazy;
207: sp[x].lazy = 0; 208: } 209: } 210: 211: void update(int l, int r, int c )
212: { 213: RotateTo(l-1,0); 214: RotateTo(r+1,root); 215: sp[keyTree].lazy += c;216: sp[keyTree].sum += (long long) c * sp[keyTree].sz;
217: } 218: 219: // query for the interval [l,r]
220: void query(int l, int r)
221: { 222: RotateTo(l-1,0); 223: RotateTo(r+1,root);224: // int keyTree = sp [sp[root].child[1] ].child[0];
225: printf("%lld\n",sp[keyTree].sum);
226: } 227: } spt; 228: 229: int abs(int x)
230: {231: if(x < 0) return -x;
232: else return x;
233: }234: int main()
235: { 236: 237: //freopen("1.txt","r",stdin);
238: int n,m;
239: cin>>n; 240: m = 0;241: for(int i=0; i<n; i++)
242: scanf("%d",&num[i]);
243: spt.Init(0);244: int ret = 0;
245: while(m!=n)
246: {247: pair<int,bool> state = spt.Insert(num[m]);
248: if(state.second != 0)
249: {250: int pre = spt.findPrefix(state.first);
251: int nxt = spt.findSuffix(state.first);
252: int ans = INF;
253: if(pre)
254: ans = abs(num[m] - spt.sp[pre].val);255: if(nxt)
256: {257: int x = abs(num[m] - spt.sp[nxt].val);
258: ans = std::min(ans, x ); 259: } 260: 261: if(pre == 0 && nxt == 0) ans = num[0];
262: // cout<<num[m]<<" "<<pre<<" "<<nxt<<" "<<ans<<endl;
263: ret += ans; 264: } 265: m++; 266: } 267: cout<<ret<<endl;;268: return 0;
269: } 270: 271: 272: BZOJ 1588 营业额统计 Splay,布布扣,bubuko.com
标签:des style class code ext width color int html cti htm
原文地址:http://www.cnblogs.com/sosi/p/3700937.html