第三周 3.13-3.19
3.13
HDU 5643 King's Game
等价于k = n + 1约瑟夫。神奇。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 int main(void) 6 { 7 int T; 8 scanf("%d", &T); 9 while(T--) 10 { 11 int x, ans = 0; 12 scanf("%d", &x); 13 for(int i = 1; i <= x; i++) ans = (ans + x + 1) % i; 14 printf("%d\n", ans + 1); 15 } 16 return 0; 17 }
HDU 5644 King's Pilots
不会建图。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 int p[222], s[11], t[11]; 8 9 //SPFA_min_cost_flow 10 const int INF = 1e9; 11 const int maxn = 1e5 + 10; 12 int dist[maxn], vis[maxn]; 13 int pv[maxn], pe[maxn]; 14 int cnt, h[maxn]; 15 16 struct edge 17 { 18 int to, pre, cap, cost; 19 } e[maxn<<1]; 20 21 void init()//Don't forget 22 { 23 cnt = 0; 24 memset(h, -1, sizeof(h)); 25 } 26 27 void add(int from, int to, int cap, int cost) 28 { 29 e[cnt].pre = h[from]; 30 e[cnt].to = to; 31 e[cnt].cap = cap; 32 e[cnt].cost = cost; 33 h[from] = cnt; 34 cnt++; 35 } 36 37 void ad(int from, int to, int cap, int cost) 38 { 39 add(from, to, cap, cost); 40 add(to, from, 0, -cost); 41 } 42 43 int min_cost_flow(int s, int t, int f) 44 { 45 int ret = 0; 46 while(f > 0) 47 { 48 memset(vis, 0, sizeof(vis)); 49 for(int i = 0; i < maxn; i++) dist[i] = INF; 50 dist[s] = 0; 51 queue<int> q; 52 q.push(s); 53 while(!q.empty()) 54 { 55 int v = q.front(); q.pop(); 56 vis[v] = 0; 57 for(int i = h[v]; i >= 0; i = e[i].pre) 58 { 59 int to = e[i].to, cap = e[i].cap, cost = e[i].cost; 60 if(cap > 0 && dist[to] > dist[v] + cost) 61 { 62 pv[to] = v, pe[to] = i; 63 dist[to] = dist[v] + cost; 64 if(!vis[to]) q.push(to); 65 vis[to] = 1; 66 } 67 } 68 } 69 70 if(dist[t] == INF) return -1;//modify here 71 72 int d = f; 73 for(int v = t; v != s; v = pv[v]) 74 d = min(d, e[pe[v]].cap); 75 f -= d; 76 ret += d * dist[t]; 77 for(int v = t; v != s; v = pv[v]) 78 { 79 e[pe[v]].cap -= d; 80 e[pe[v]^1].cap += d; 81 } 82 } 83 return ret; 84 } 85 86 int main(void) 87 { 88 int T; 89 scanf("%d", &T); 90 while(T--) 91 { 92 init(); 93 int n, k, m, P, Q, sum = 0; 94 scanf("%d %d", &n, &k); 95 for(int i = 1; i <= n; i++) scanf("%d", p + i), sum += p[i]; 96 scanf("%d %d %d", &m, &P, &Q); 97 for(int i = 1; i <= m; i++) scanf("%d %d", s + i, t + i); 98 int st = 2 * n + 1, ed = st + 1; 99 for(int i = 1; i <= n; i++) ad(st, i, p[i], 0); 100 for(int i = 1; i <= n; i++) ad(i + n, ed, p[i], 0); 101 ad(st, 1 + n, k, 0); 102 for(int i = P; i <= n; i++) ad(st, i + n, INF, Q); 103 for(int i = 1; i < n; i++) ad(i, i + 1, INF, 0); 104 for(int i = 1; i < n; i++) ad(i + n, i + n + 1, INF, 0); 105 for(int i = 1; i <= m; i++) 106 for(int j = 1; j + t[i] <= n; j++) 107 ad(j, j + t[i] + n, INF, s[i]); 108 int ans = min_cost_flow(st, ed, sum); 109 if(ans == -1) puts("No solution"); 110 else printf("%d\n", ans); 111 } 112 return 0; 113 }
3.14
BZOJ 1503 [NOI2004]郁闷的出纳员
板子仍需完善。
#include <iostream> #include <cstdio> using namespace std; const int maxn = 1e5 + 10; struct Splay { int rt, tot; int sz[maxn], cnt[maxn]; int fa[maxn], ch[maxn][2]; int val[maxn]; void init() { rt = tot = 0; sz[0] = cnt[0] = 0; fa[0] = ch[0][0] = ch[0][1] = 0; } void gather(int x) { sz[x] = cnt[x] + sz[ch[x][0]] + sz[ch[x][1]]; } void Rotate(int x, int d) { int y = fa[x]; ch[y][d^1] = ch[x][d]; if(ch[x][d]) fa[ch[x][d]] = y; fa[x] = fa[y]; if(fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; ch[x][d] = y; fa[y] = x; gather(y); } void splay(int x, int t) { while(fa[x] != t) { if(fa[fa[x]] == t) Rotate(x, ch[fa[x]][0]==x); else { int y = fa[x], z = fa[y]; int d = ch[z][0] == y; if(ch[y][d] == x) Rotate(x, d^1), Rotate(x, d); else Rotate(y, d), Rotate(x, d); } } gather(x); if(t == 0) rt = x; } int Newnode(int v, int f) { tot++; cnt[tot] = sz[tot] = 1; ch[tot][0] = ch[tot][1] = 0; val[tot] = v; fa[tot] = f; if(f) ch[f][v>val[f]] = tot; return tot; } void Insert(int x, int f, int v) { if(!x) { splay(Newnode(v, f), 0); return; } if(v == val[x]) cnt[x]++, sz[x]++; else { Insert(ch[x][v>val[x]], x, v); gather(x); } } int Find_kth(int k, int t) { int x = rt; while(1) { if(k <= sz[ch[x][0]]) x = ch[x][0]; else if(k > sz[ch[x][0]] + cnt[x]) { k -= sz[ch[x][0]] + cnt[x]; x = ch[x][1]; } else { splay(x, t); return val[x]; } } } int Del(int lb, int x) { int ret = 0; if(!x) return ret; if(val[x] >= lb) ret += Del(lb, ch[x][0]), gather(x); else { ret += sz[ch[x][0]] + cnt[x]; if(fa[x]) ch[fa[x]][ch[fa[x]][1]==x] = ch[x][1]; else rt = ch[x][1]; if(ch[x][1]) { fa[ch[x][1]] = fa[x]; ret += Del(lb, ch[x][1]); } } return ret; } } sp; int main(void) { int n, lb; scanf("%d %d", &n, &lb); sp.init(); int cur = 0, sum = 0; while(n--) { int k; char op[10]; scanf("%s %d", op, &k); if(op[0] == 'I') { if(k < lb) continue; sp.Insert(sp.rt, 0, k - cur); } else if(op[0] == 'A') cur += k; else if(op[0] == 'S') { cur -= k; sum += sp.Del(lb-cur, sp.rt); } else { if(sp.sz[sp.rt] < k) puts("-1"); else printf("%d\n", sp.Find_kth(sp.sz[sp.rt] - k + 1, 0) + cur); } } printf("%d\n", sum); return 0; }
3.15
BZOJ 1208 [HNOI2004]宠物收养所
板子++。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int maxn = 2e5 + 10; 5 const int mod = 1e6; 6 7 struct Splay 8 { 9 int rt, tot; 10 int sz[maxn], cnt[maxn]; 11 int fa[maxn], ch[maxn][2]; 12 int tag[maxn], val[maxn]; 13 14 void init() 15 { 16 rt = tot = 0; 17 sz[0] = cnt[0] = tag[0] = 0; 18 fa[0] = ch[0][0] = ch[0][1] = 0; 19 } 20 21 void gather(int x) 22 { 23 sz[x] = cnt[x] + sz[ch[x][0]] + sz[ch[x][1]]; 24 } 25 26 void push(int x) 27 { 28 if(tag[x]) 29 { 30 if(ch[x][0]) 31 { 32 33 //... 34 35 } 36 37 if(ch[x][1]) 38 { 39 40 //... 41 42 } 43 tag[x] = 0; 44 } 45 } 46 47 int Newnode(int v, int f) 48 { 49 tot++; 50 cnt[tot] = sz[tot] = 1; 51 ch[tot][0] = ch[tot][1] = 0; 52 val[tot] = v; 53 fa[tot] = f; 54 if(f) ch[f][v>val[f]] = tot; 55 tag[tot] = 0; 56 return tot; 57 } 58 59 void Insert(int x, int f, int v) 60 { 61 if(!x) 62 { 63 splay(Newnode(v, f), 0); 64 return; 65 } 66 if(v == val[x]) cnt[x]++, sz[x]++; 67 else 68 { 69 Insert(ch[x][v>val[x]], x, v); 70 gather(x); 71 } 72 } 73 74 void Build() 75 { 76 77 78 79 } 80 81 void Rotate(int x, int d) 82 { 83 int y = fa[x]; 84 push(y), push(x); 85 ch[y][d^1] = ch[x][d]; 86 if(ch[x][d]) fa[ch[x][d]] = y; 87 fa[x] = fa[y]; 88 if(fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; 89 ch[x][d] = y; 90 fa[y] = x; 91 gather(y); 92 } 93 94 void splay(int x, int t) 95 { 96 while(fa[x] != t) 97 { 98 if(fa[fa[x]] == t) Rotate(x, ch[fa[x]][0]==x); 99 else 100 { 101 int y = fa[x], z = fa[y]; 102 int d = ch[z][0] == y; 103 if(ch[y][d] == x) Rotate(x, d^1), Rotate(x, d); 104 else Rotate(y, d), Rotate(x, d); 105 } 106 } 107 gather(x); 108 if(t == 0) rt = x; 109 } 110 111 int Find_kth(int k, int t) // find kth smallest 112 { 113 if(!rt || k > sz[rt]) return 0; 114 int x = rt; push(x); 115 while(1) 116 { 117 if(k <= sz[ch[x][0]]) x = ch[x][0]; 118 else if(k > sz[ch[x][0]] + cnt[x]) 119 { 120 k -= sz[ch[x][0]] + cnt[x]; 121 x = ch[x][1]; 122 } 123 else 124 { 125 splay(x, t); 126 return x; // val[x] 127 } 128 push(x); 129 } 130 } 131 132 int Find_val(int v) // find x == v 133 { 134 if(!rt) return 0; 135 int x = rt; 136 while(x) 137 { 138 push(x); 139 if(val[x] == v) break; 140 x = ch[x][v>val[x]]; 141 } 142 if(x) splay(x, 0); 143 return x; 144 } 145 146 int Find_pre(int x, int v) 147 { 148 if(!x) return -1; 149 if(val[x] <= v) 150 { 151 int y = Find_pre(ch[x][1], v); 152 return y == -1 ? x : y; 153 } 154 else return Find_pre(ch[x][0], v); 155 } 156 157 int Find_suc(int x, int v) 158 { 159 if(!x) return -1; 160 if(val[x] >= v) 161 { 162 int y = Find_suc(ch[x][0], v); 163 return y == -1 ? x : y; 164 } 165 else return Find_suc(ch[x][1], v); 166 } 167 168 int Del(int lb, int x) // delete x < lb 169 { 170 int ret = 0; 171 if(!x) return ret; 172 push(x); 173 if(val[x] >= lb) ret += Del(lb, ch[x][0]), gather(x); 174 else 175 { 176 ret += sz[ch[x][0]] + cnt[x]; 177 if(fa[x]) ch[fa[x]][ch[fa[x]][1]==x] = ch[x][1]; 178 else rt = ch[x][1]; 179 if(ch[x][1]) 180 { 181 fa[ch[x][1]] = fa[x]; 182 ret += Del(lb, ch[x][1]); 183 } 184 } 185 return ret; 186 } 187 188 void Del_root() 189 { 190 if(!rt) return; 191 if(!ch[rt][0]) 192 { 193 if(!ch[rt][1]) {rt = 0; return;} 194 rt = ch[rt][1]; 195 } 196 else 197 { 198 Find_kth(sz[ch[rt][0]], rt); 199 ch[ch[rt][0]][1] = ch[rt][1]; 200 rt = fa[ch[rt][1]] = ch[rt][0]; 201 } 202 fa[rt] = 0; 203 } 204 205 } sp; 206 207 int main(void) 208 { 209 sp.init(); 210 int n; 211 scanf("%d", &n); 212 int type = -1, sum = 0; 213 while(n--) 214 { 215 int a, b; 216 scanf("%d %d", &a, &b); 217 if(type == -1) 218 { 219 sp.Insert(sp.rt, 0, b); 220 type = a; 221 } 222 else if(type == a) sp.Insert(sp.rt, 0, b); 223 else 224 { 225 int op; 226 int x = sp.Find_pre(sp.rt, b); 227 int y = sp.Find_suc(sp.rt, b); 228 if(x == -1) op = y; 229 else if(y == -1) op = x; 230 else 231 { 232 int dx = b - sp.val[x]; 233 int dy = sp.val[y] - b; 234 op = dx <= dy ? x : y; 235 } 236 int d = sp.val[op] - b; 237 if(d < 0) d = -d; 238 sum = (sum + d) % mod; 239 sp.splay(op, 0); 240 sp.Del_root(); 241 if(!sp.sz[sp.rt]) type = -1; 242 } 243 } 244 printf("%d\n", sum); 245 return 0; 246 }
3.16
POJ 3468 A Simple Problem with Integers
板子堆成这样就很尴尬了QAQ
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long LL; 5 const int maxn = 1e6 + 10; 6 LL a[maxn]; 7 int N, Q; 8 9 struct Splay 10 { 11 int rt, tot; 12 int sz[maxn], cnt[maxn]; 13 int fa[maxn], ch[maxn][2]; 14 LL tag[maxn], val[maxn], sum[maxn]; 15 16 // fundamental 17 18 void init() 19 { 20 rt = tot = 0; 21 sz[0] = cnt[0] = 0; 22 fa[0] = ch[0][0] = ch[0][1] = 0; 23 tag[0] = val[0] = sum[0] = 0; 24 } 25 26 void gather(int x) 27 { 28 sz[x] = cnt[x] + sz[ch[x][0]] + sz[ch[x][1]]; 29 sum[x] = val[x] + sum[ch[x][0]] + sum[ch[x][1]]; 30 } 31 32 void push(int x) 33 { 34 if(tag[x]) 35 { 36 if(ch[x][0]) 37 { 38 val[ch[x][0]] += tag[x]; 39 tag[ch[x][0]] += tag[x]; 40 sum[ch[x][0]] += tag[x] * sz[ch[x][0]]; 41 } 42 if(ch[x][1]) 43 { 44 val[ch[x][1]] += tag[x]; 45 tag[ch[x][1]] += tag[x]; 46 sum[ch[x][1]] += tag[x] * sz[ch[x][1]]; 47 } 48 tag[x] = 0; 49 } 50 } 51 52 int Newnode(LL v, int f) 53 { 54 tot++; 55 cnt[tot] = sz[tot] = 1; 56 ch[tot][0] = ch[tot][1] = 0; 57 fa[tot] = f, tag[tot] = 0; 58 val[tot] = sum[tot] = v; 59 if(!f) rt = tot; 60 return tot; 61 } 62 63 void Rotate(int x, int d) 64 { 65 int y = fa[x]; 66 push(y), push(x); 67 ch[y][d^1] = ch[x][d]; 68 if(ch[x][d]) fa[ch[x][d]] = y; 69 fa[x] = fa[y]; 70 if(fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; 71 ch[x][d] = y; 72 fa[y] = x; 73 gather(y); 74 } 75 76 void splay(int x, int t) 77 { 78 push(x); 79 while(fa[x] != t) 80 { 81 if(fa[fa[x]] == t) Rotate(x, ch[fa[x]][0]==x); 82 else 83 { 84 int y = fa[x], z = fa[y]; 85 int d = ch[z][0] == y; 86 if(ch[y][d] == x) Rotate(x, d^1), Rotate(x, d); 87 else Rotate(y, d), Rotate(x, d); 88 } 89 } 90 gather(x); 91 if(t == 0) rt = x; 92 } 93 94 // point 95 96 void Insert(int x, int f, int v) 97 { 98 if(!x) 99 { 100 x = Newnode(v, f); 101 if(f) ch[f][v>val[f]] = x; 102 splay(x, 0); 103 return; 104 } 105 if(v == val[x]) cnt[x]++, sz[x]++; 106 else 107 { 108 Insert(ch[x][v>val[x]], x, v); 109 gather(x); 110 } 111 } 112 113 int Find_kth(int k, int t) // find kth smallest 114 { 115 if(!rt || k > sz[rt]) return 0; 116 int x = rt; 117 while(1) 118 { 119 push(x); 120 if(k <= sz[ch[x][0]]) x = ch[x][0]; 121 else if(k > sz[ch[x][0]] + cnt[x]) 122 { 123 k -= sz[ch[x][0]] + cnt[x]; 124 x = ch[x][1]; 125 } 126 else 127 { 128 splay(x, t); 129 return x; // val[x] 130 } 131 } 132 } 133 134 int Find_val(int v) // find x == v 135 { 136 if(!rt) return 0; 137 int x = rt; 138 while(x) 139 { 140 push(x); 141 if(val[x] == v) break; 142 x = ch[x][v>val[x]]; 143 } 144 if(x) splay(x, 0); 145 return x; 146 } 147 148 int Find_pre(int x, int v) 149 { 150 if(!x) return -1; 151 if(val[x] <= v) 152 { 153 int y = Find_pre(ch[x][1], v); 154 return y == -1 ? x : y; 155 } 156 else return Find_pre(ch[x][0], v); 157 } 158 159 int Find_suc(int x, int v) 160 { 161 if(!x) return -1; 162 if(val[x] >= v) 163 { 164 int y = Find_suc(ch[x][0], v); 165 return y == -1 ? x : y; 166 } 167 else return Find_suc(ch[x][1], v); 168 } 169 170 int Del(int lb, int x) // delete x < lb 171 { 172 int ret = 0; 173 if(!x) return ret; 174 push(x); 175 if(val[x] >= lb) ret += Del(lb, ch[x][0]), gather(x); 176 else 177 { 178 ret += sz[ch[x][0]] + cnt[x]; 179 if(fa[x]) ch[fa[x]][ch[fa[x]][1]==x] = ch[x][1]; 180 else rt = ch[x][1]; 181 if(ch[x][1]) 182 { 183 fa[ch[x][1]] = fa[x]; 184 ret += Del(lb, ch[x][1]); 185 } 186 } 187 return ret; 188 } 189 190 void Del_root() 191 { 192 if(!rt) return; 193 push(rt); 194 if(!ch[rt][0]) 195 { 196 if(!ch[rt][1]) {rt = 0; return;} 197 rt = ch[rt][1]; 198 } 199 else 200 { 201 Find_kth(sz[ch[rt][0]], rt); 202 ch[ch[rt][0]][1] = ch[rt][1]; 203 rt = fa[ch[rt][1]] = ch[rt][0]; 204 } 205 fa[rt] = 0; 206 } 207 208 // range 209 210 int Build(int l, int r, int f) 211 { 212 if(l > r) return 0; 213 int mid = (l + r) / 2; 214 int x = Newnode(a[mid], f); 215 ch[x][0] = Build(l, mid - 1, x); 216 ch[x][1] = Build(mid + 1, r, x); 217 gather(x); 218 return x; 219 } 220 221 void modify(int l, int r, LL v) 222 { 223 int tar; 224 if(l == 1 && r == N) tar = rt; 225 else if(l == 1) Find_kth(r+1, 0), tar = ch[rt][0]; 226 else if(r == N) Find_kth(l-1, 0), tar = ch[rt][1]; 227 else Find_kth(l-1, Find_kth(r+1, 0)), tar = ch[ch[rt][0]][1]; 228 tag[tar] += v, val[tar] += v; 229 sum[tar] += v * sz[tar]; 230 while(fa[tar]) tar = fa[tar], gather(tar); 231 } 232 233 LL query(int l, int r) 234 { 235 int tar; 236 if(l == 1 && r == N) tar = rt; 237 else if(l == 1) Find_kth(r+1, 0), tar = ch[rt][0]; 238 else if(r == N) Find_kth(l-1, 0), tar = ch[rt][1]; 239 else Find_kth(l-1, Find_kth(r+1, 0)), tar = ch[ch[rt][0]][1]; 240 return sum[tar]; 241 } 242 243 } sp; 244 245 int main(void) 246 { 247 while(~scanf("%d %d", &N, &Q)) 248 { 249 sp.init(); 250 for(int i = 1; i <= N; i++) scanf("%I64d", a + i); 251 sp.Build(1, N, 0); 252 while(Q--) 253 { 254 char op[10]; 255 LL x, y, z; 256 scanf("%s", op); 257 if(op[0] == 'C') 258 { 259 scanf("%I64d %I64d %I64d", &x, &y, &z); 260 sp.modify(x, y, z); 261 } 262 else 263 { 264 scanf("%I64d %I64d", &x, &y); 265 printf("%I64d\n", sp.query(x, y)); 266 } 267 } 268 } 269 return 0; 270 }
3.17
HDU 1890 Robotic Sort
发现上面的都是错的呢~虽然也不保证现在就是对的~
QAQ改完板上面的全部重新交一次。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1e5 + 10; 6 int N; 7 8 struct M 9 { 10 int id, h, p; 11 } m[maxn]; 12 13 bool cmp1(M a, M b) 14 { 15 if(a.h != b.h) return a.h < b.h; 16 return a.id < b.id; 17 } 18 19 bool cmp2(M a, M b) 20 { 21 return a.id < b.id; 22 } 23 24 struct Splay 25 { 26 int rt, tot; 27 int sz[maxn], cnt[maxn]; 28 int fa[maxn], ch[maxn][2]; 29 int tag[maxn], val[maxn], pos[maxn]; 30 31 // fundamental 32 33 void init() 34 { 35 rt = tot = 0; 36 sz[0] = cnt[0] = 0; 37 fa[0] = ch[0][0] = ch[0][1] = 0; 38 tag[0] = val[0] = 0; 39 } 40 41 void gather(int x) 42 { 43 sz[x] = cnt[x] + sz[ch[x][0]] + sz[ch[x][1]]; 44 } 45 46 void push(int x) 47 { 48 if(tag[x]) 49 { 50 if(ch[x][0]) tag[ch[x][0]] ^= 1; 51 if(ch[x][1]) tag[ch[x][1]] ^= 1; 52 swap(ch[x][0], ch[x][1]); 53 tag[x] = 0; 54 } 55 } 56 57 int Newnode(int v, int f) 58 { 59 tot++; 60 cnt[tot] = sz[tot] = 1; 61 ch[tot][0] = ch[tot][1] = 0; 62 fa[tot] = f, tag[tot] = 0; 63 val[tot] = v; 64 pos[v] = tot; 65 if(!f) rt = tot; 66 return tot; 67 } 68 69 void Rotate(int x, int d) 70 { 71 int y = fa[x]; 72 push(y), push(x); 73 ch[y][d^1] = ch[x][d]; 74 if(ch[x][d]) fa[ch[x][d]] = y; 75 fa[x] = fa[y]; 76 if(fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; 77 ch[x][d] = y; 78 fa[y] = x; 79 gather(y); 80 } 81 82 void splay(int x, int t) 83 { 84 push(x); 85 while(fa[x] != t) 86 { 87 push(fa[fa[x]]), push(fa[x]), push(x); 88 if(fa[fa[x]] == t) Rotate(x, ch[fa[x]][0]==x); 89 else 90 { 91 int y = fa[x], z = fa[y]; 92 int d = ch[z][0] == y; 93 if(ch[y][d] == x) Rotate(x, d^1), Rotate(x, d); 94 else Rotate(y, d), Rotate(x, d); 95 } 96 } 97 gather(x); 98 if(t == 0) rt = x; 99 } 100 101 // point 102 103 void Insert(int x, int f, int v) 104 { 105 if(!x) 106 { 107 x = Newnode(v, f); 108 if(f) ch[f][v>val[f]] = x; 109 splay(x, 0); 110 return; 111 } 112 if(v == val[x]) cnt[x]++, sz[x]++; 113 else 114 { 115 Insert(ch[x][v>val[x]], x, v); 116 gather(x); 117 } 118 } 119 120 int Find_kth(int k, int t) // find kth smallest 121 { 122 if(!rt || k > sz[rt]) return 0; 123 int x = rt; 124 while(1) 125 { 126 push(x); 127 if(k <= sz[ch[x][0]]) x = ch[x][0]; 128 else if(k > sz[ch[x][0]] + cnt[x]) 129 { 130 k -= sz[ch[x][0]] + cnt[x]; 131 x = ch[x][1]; 132 } 133 else 134 { 135 splay(x, t); 136 return x; // val[x] 137 } 138 } 139 } 140 141 int Find_val(int v) // find x == v 142 { 143 if(!rt) return 0; 144 int x = rt; 145 while(x) 146 { 147 push(x); 148 if(val[x] == v) break; 149 x = ch[x][v>val[x]]; 150 } 151 if(x) splay(x, 0); 152 return x; 153 } 154 155 int Find_pre(int x, int v) 156 { 157 if(!x) return -1; 158 if(val[x] <= v) 159 { 160 int y = Find_pre(ch[x][1], v); 161 return y == -1 ? x : y; 162 } 163 else return Find_pre(ch[x][0], v); 164 } 165 166 int Find_suc(int x, int v) 167 { 168 if(!x) return -1; 169 if(val[x] >= v) 170 { 171 int y = Find_suc(ch[x][0], v); 172 return y == -1 ? x : y; 173 } 174 else return Find_suc(ch[x][1], v); 175 } 176 177 int Del(int lb, int x) // delete x < lb 178 { 179 int ret = 0; 180 if(!x) return ret; 181 push(x); 182 if(val[x] >= lb) ret += Del(lb, ch[x][0]), gather(x); 183 else 184 { 185 ret += sz[ch[x][0]] + cnt[x]; 186 if(fa[x]) ch[fa[x]][ch[fa[x]][1]==x] = ch[x][1]; 187 else rt = ch[x][1]; 188 if(ch[x][1]) 189 { 190 fa[ch[x][1]] = fa[x]; 191 ret += Del(lb, ch[x][1]); 192 } 193 } 194 return ret; 195 } 196 197 void Del_root() 198 { 199 if(!rt) return; 200 push(rt); 201 if(!ch[rt][0]) 202 { 203 if(!ch[rt][1]) {rt = 0; return;} 204 rt = ch[rt][1]; 205 } 206 else 207 { 208 Find_kth(sz[ch[rt][0]], rt); 209 ch[ch[rt][0]][1] = ch[rt][1]; 210 rt = fa[ch[rt][1]] = ch[rt][0]; 211 } 212 fa[rt] = 0; 213 if(rt) gather(rt); 214 } 215 216 // range 217 218 int Build(int l, int r, int f) 219 { 220 if(l > r) return 0; 221 int mid = (l + r) / 2; 222 int x = Newnode(m[mid].p, f); 223 ch[x][0] = Build(l, mid - 1, x); 224 ch[x][1] = Build(mid + 1, r, x); 225 gather(x); 226 return x; 227 } 228 229 void modify(int l, int r) 230 { 231 int tar; 232 if(l == 1 && r == N) tar = rt; 233 else if(l == 1) Find_kth(r+1, 0), tar = ch[rt][0]; 234 else if(r == N) Find_kth(l-1, 0), tar = ch[rt][1]; 235 else Find_kth(l-1, Find_kth(r+1, 0)), tar = ch[ch[rt][0]][1]; 236 if(ch[tar][0]) tag[ch[tar][0]] ^= 1; 237 if(ch[tar][1]) tag[ch[tar][1]] ^= 1; 238 swap(ch[tar][0], ch[tar][1]); 239 } 240 241 } sp; 242 243 int main(void) 244 { 245 while(~scanf("%d", &N) && N) 246 { 247 sp.init(); 248 for(int i = 1; i <= N; i++) 249 { 250 scanf("%d", &m[i].h); 251 m[i].id = i; 252 } 253 sort(m + 1, m + N + 1, cmp1); 254 for(int i = 1; i <= N; i++) m[i].p = i; 255 sort(m + 1, m + N + 1, cmp2); 256 sp.Build(1, N, 0); 257 for(int i = 1; i <= N; i++) 258 { 259 sp.splay(sp.pos[i], 0); 260 int p = sp.sz[sp.ch[sp.rt][0]] + sp.cnt[sp.rt]; 261 printf("%d%c", p + i - 1, i == N ? '\n' : ' '); 262 if(sp.ch[sp.rt][0]) sp.tag[sp.ch[sp.rt][0]] ^= 1; 263 sp.Del_root(); 264 } 265 } 266 return 0; 267 }
HDU 3487 Play with Chain
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 3e5 + 10; 6 int N, M, fir; 7 8 struct Splay 9 { 10 int rt, tot; 11 int sz[maxn], cnt[maxn]; 12 int fa[maxn], ch[maxn][2]; 13 int tag[maxn], val[maxn]; 14 15 // fundamental 16 17 void init() 18 { 19 rt = tot = 0; 20 sz[0] = cnt[0] = 0; 21 fa[0] = ch[0][0] = ch[0][1] = 0; 22 tag[0] = val[0] = 0; 23 } 24 25 void gather(int x) 26 { 27 sz[x] = cnt[x] + sz[ch[x][0]] + sz[ch[x][1]]; 28 } 29 30 void push(int x) 31 { 32 if(tag[x]) 33 { 34 if(ch[x][0]) tag[ch[x][0]] ^= 1; 35 if(ch[x][1]) tag[ch[x][1]] ^= 1; 36 swap(ch[x][0], ch[x][1]); 37 tag[x] = 0; 38 } 39 } 40 41 int Newnode(int v, int f) 42 { 43 tot++; 44 cnt[tot] = sz[tot] = 1; 45 ch[tot][0] = ch[tot][1] = 0; 46 fa[tot] = f, tag[tot] = 0; 47 val[tot] = v; 48 if(!f) rt = tot; 49 return tot; 50 } 51 52 void Rotate(int x, int d) 53 { 54 int y = fa[x]; 55 push(y), push(x); 56 ch[y][d^1] = ch[x][d]; 57 if(ch[x][d]) fa[ch[x][d]] = y; 58 fa[x] = fa[y]; 59 if(fa[y]) ch[fa[y]][ch[fa[y]][1]==y] = x; 60 ch[x][d] = y; 61 fa[y] = x; 62 gather(y); 63 } 64 65 void splay(int x, int t) 66 { 67 push(x); 68 while(fa[x] != t) 69 { 70 push(fa[fa[x]]), push(fa[x]), push(x); 71 if(fa[fa[x]] == t) Rotate(x, ch[fa[x]][0]==x); 72 else 73 { 74 int y = fa[x], z = fa[y]; 75 int d = ch[z][0] == y; 76 if(ch[y][d] == x) Rotate(x, d^1), Rotate(x, d); 77 else Rotate(y, d), Rotate(x, d); 78 } 79 } 80 gather(x); 81 if(t == 0) rt = x; 82 } 83 84 // point 85 86 void Insert(int x, int f, int v) 87 { 88 if(!x) 89 { 90 x = Newnode(v, f); 91 if(f) ch[f][v>val[f]] = x; 92 splay(x, 0); 93 return; 94 } 95 if(v == val[x]) cnt[x]++, sz[x]++; 96 else 97 { 98 Insert(ch[x][v>val[x]], x, v); 99 gather(x); 100 } 101 } 102 103 int Find_kth(int k, int t) // find kth smallest 104 { 105 if(!rt || k > sz[rt]) return 0; 106 int x = rt; 107 while(1) 108 { 109 push(x); 110 if(k <= sz[ch[x][0]]) x = ch[x][0]; 111 else if(k > sz[ch[x][0]] + cnt[x]) 112 { 113 k -= sz[ch[x][0]] + cnt[x]; 114 x = ch[x][1]; 115 } 116 else 117 { 118 splay(x, t); 119 return x; // val[x] 120 } 121 } 122 } 123 124 int Find_val(int v) // find x == v 125 { 126 if(!rt) return 0; 127 int x = rt; 128 while(x) 129 { 130 push(x); 131 if(val[x] == v) break; 132 x = ch[x][v>val[x]]; 133 } 134 if(x) splay(x, 0); 135 return x; 136 } 137 138 int Find_pre(int x, int v) 139 { 140 if(!x) return -1; 141 if(val[x] <= v) 142 { 143 int y = Find_pre(ch[x][1], v); 144 return y == -1 ? x : y; 145 } 146 else return Find_pre(ch[x][0], v); 147 } 148 149 int Find_suc(int x, int v) 150 { 151 if(!x) return -1; 152 if(val[x] >= v) 153 { 154 int y = Find_suc(ch[x][0], v); 155 return y == -1 ? x : y; 156 } 157 else return Find_suc(ch[x][1], v); 158 } 159 160 int Del(int lb, int x) // delete x < lb 161 { 162 int ret = 0; 163 if(!x) return ret; 164 push(x); 165 if(val[x] >= lb) ret += Del(lb, ch[x][0]), gather(x); 166 else 167 { 168 ret += sz[ch[x][0]] + cnt[x]; 169 if(fa[x]) ch[fa[x]][ch[fa[x]][1]==x] = ch[x][1]; 170 else rt = ch[x][1]; 171 if(ch[x][1]) 172 { 173 fa[ch[x][1]] = fa[x]; 174 ret += Del(lb, ch[x][1]); 175 } 176 } 177 return ret; 178 } 179 180 void Del_root() 181 { 182 if(!rt) return; 183 push(rt); 184 if(!ch[rt][0]) 185 { 186 if(!ch[rt][1]) {rt = 0; return;} 187 rt = ch[rt][1]; 188 } 189 else 190 { 191 Find_kth(sz[ch[rt][0]], rt); 192 ch[ch[rt][0]][1] = ch[rt][1]; 193 rt = fa[ch[rt][1]] = ch[rt][0]; 194 } 195 fa[rt] = 0; 196 if(rt) gather(rt); 197 } 198 199 // range 200 201 int Build(int l, int r, int f) 202 { 203 if(l > r) return 0; 204 int mid = (l + r) / 2; 205 int x = Newnode(mid, f); 206 ch[x][0] = Build(l, mid - 1, x); 207 ch[x][1] = Build(mid + 1, r, x); 208 gather(x); 209 return x; 210 } 211 212 void flip(int l, int r) 213 { 214 int tar; 215 if(l == 1 && r == N) tar = rt; 216 else if(l == 1) Find_kth(r+1, 0), tar = ch[rt][0]; 217 else if(r == N) Find_kth(l-1, 0), tar = ch[rt][1]; 218 else Find_kth(l-1, Find_kth(r+1, 0)), tar = ch[ch[rt][0]][1]; 219 if(ch[tar][0]) tag[ch[tar][0]] ^= 1; 220 if(ch[tar][1]) tag[ch[tar][1]] ^= 1; 221 swap(ch[tar][0], ch[tar][1]); 222 } 223 224 void change(int l, int r, int p) 225 { 226 if(l == 1 && r == N) return; 227 int tar; 228 if(l == 1 && r == N) tar = rt; 229 else if(l == 1) Find_kth(r+1, 0), tar = ch[rt][0]; 230 else if(r == N) Find_kth(l-1, 0), tar = ch[rt][1]; 231 else Find_kth(l-1, Find_kth(r+1, 0)), tar = ch[ch[rt][0]][1]; 232 if(fa[tar]) ch[fa[tar]][ch[fa[tar]][1]==tar] = 0; 233 for(int i = fa[tar]; i; i = fa[i]) gather(i); 234 if(p == 0) 235 { 236 Find_kth(1, 0); 237 ch[rt][0] = tar; 238 fa[tar] = rt; 239 gather(rt); 240 } 241 else if(p == N - r + l - 1) 242 { 243 Find_kth(N - r + l - 1, 0); 244 ch[rt][1] = tar; 245 fa[tar] = rt; 246 gather(rt); 247 } 248 else 249 { 250 Find_kth(p+1, Find_kth(p, 0)); 251 ch[ch[rt][1]][0] = tar; 252 fa[tar] = ch[rt][1]; 253 gather(fa[tar]), gather(fa[fa[tar]]); 254 } 255 } 256 257 void print(int x) 258 { 259 if(!x) return; 260 push(x); 261 print(ch[x][0]); 262 if(fir) putchar(' '); 263 printf("%d", val[x]), fir = 1; 264 print(ch[x][1]); 265 } 266 267 } sp; 268 269 int main(void) 270 { 271 while(~scanf("%d %d", &N, &M)) 272 { 273 if(N == -1 && M == -1) break; 274 sp.init(); 275 sp.Build(1, N, 0); 276 for(int i = 1; i <= M; i++) 277 { 278 char op[10]; 279 int a, b, c; 280 scanf("%s", op); 281 if(op[0] == 'C') 282 { 283 scanf("%d %d %d", &a, &b, &c); 284 sp.change(a, b, c); 285 } 286 else 287 { 288 scanf("%d %d", &a, &b); 289 sp.flip(a, b); 290 } 291 } 292 fir = 0; 293 sp.print(sp.rt); 294 puts(""); 295 } 296 return 0; 297 }
3.18
CF 632 E Thief in a Shop
你们CF阿有一点好就是跑的比谁都快。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1e6 + 10; 6 int a[1111], dp[maxn]; 7 8 int main(void) 9 { 10 int n, k; 11 scanf("%d %d", &n, &k); 12 for(int i = 0; i < n; i++) scanf("%d", a + i); 13 sort(a, a + n); 14 int tot = unique(a, a + n) - a, tmp = a[0]; 15 for(int i = 0; i < tot; i++) a[i] -= tmp; 16 for(int i = 1; i <= k * a[tot-1]; i++) dp[i] = k + 1; 17 for(int i = 1; i < tot; i++) 18 for(int j = a[i]; j <= k * a[tot-1]; j++) 19 dp[j] = min(dp[j], dp[j-a[i]] + 1); 20 for(int i = 0; i <= k * a[tot-1]; i++) 21 if(dp[i] <= k) printf("%d ", tmp * k + i); 22 return 0; 23 }
3.19
CF 632 F Magic Matrix
MST上任意两点之间的路径是该两点的所有路径中边权最大值最小的。
任取u、v两点,假设其MST上路径为A,A上最大的边为a,
假设存在非MST上路径B,其边权最大值小于a边,即该路径上所有边权小于a的权值,
切断a边得到两颗树,在路径B上必然存在一条边b连接这两颗树,且b边权小于a,
两颗树连接b得到了更小的生成树,与条件矛盾,证毕。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <vector> 5 using namespace std; 6 int a[3333][3333]; 7 int fa[3333]; 8 9 struct e 10 { 11 int f, t, v; 12 e(){} 13 e(int F, int T, int V): f(F), t(T), v(V){} 14 friend bool operator < (e A, e B) 15 { 16 return A.v < B.v; 17 } 18 }; 19 vector<e> ve; 20 21 void init() 22 { 23 for(int i = 0; i < 3333; i++) fa[i] = i; 24 } 25 26 int Find(int x) 27 { 28 return fa[x] == x ? x : fa[x] = Find(fa[x]); 29 } 30 31 int main(void) 32 { 33 int n; 34 scanf("%d", &n); 35 for(int i = 1; i <= n; i++) 36 for(int j = 1; j <= n; j++) 37 scanf("%d", &a[i][j]); 38 init(); 39 for(int i = 1; i <= n; i++) 40 { 41 for(int j = i; j <= n; j++) 42 { 43 if(i == j && a[i][j]) return puts("NOT MAGIC"); 44 if(a[i][j] != a[j][i]) return puts("NOT MAGIC"); 45 if(i != j) ve.push_back(e(i, j, a[i][j])); 46 } 47 } 48 sort(ve.begin(), ve.end()); 49 int sz = ve.size(), p = 0; 50 for(int i = 0; i < sz; p = ++i) 51 { 52 while(p < sz - 1 && ve[p].v == ve[p+1].v) p++; 53 for(int j = i; j <= p; j++) 54 if(Find(ve[j].f) == Find(ve[j].t)) return puts("NOT MAGIC"); 55 for(int j = i; j <= p; j++) 56 fa[Find(ve[j].f)] = Find(ve[j].t); 57 i = p; 58 } 59 puts("MAGIC"); 60 return 0; 61 }