SDOI2019 Quick Query
Consider maintaining double labeling and difficult topic is how to maintain a single point of assignment.
Push expression found directly modify the original value becomes $ \ frac {x-add} {mul} $, with the hash index can be maintained.
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define MOD 10000019 4 namespace hash{ 5 #define sz 299999 6 int h[300010], num[300010], clo[300010]; 7 int All, CLO; 8 inline int get_Num(int x) { 9 int wt = x % sz; 10 while(num[wt] != x && num[wt]) { 11 ++ wt; 12 if(wt == sz) wt = 0; 13 } 14 num[wt] = x; 15 return wt; 16 } 17 inline int upd(int x, int y, int CL) { 18 int wt = get_Num(x); 19 if(clo[wt] < CLO) h[wt] = All; 20 int ret = y - h[wt]; 21 h[wt] = y; clo[wt] = CL; 22 return ret; 23 } 24 inline int query(int x) { 25 int wt = get_Num(x); 26 if(clo[wt] < CLO) h[wt] = All, clo[wt] = CLO; 27 return h[wt]; 28 } 29 } 30 int inv[MOD+10]; 31 inline void init() { 32 inv[0] = inv[1] = 1; 33 for(int i = 2; i < MOD; ++ i) { 34 inv[i] = 1ll * inv[MOD % i] * (MOD - MOD / i) % MOD; 35 } 36 } 37 struct Node { 38 int op, x, y; 39 } que[100010]; 40 int main() { 41 //freopen("a.in", "r", stdin); 42 init(); 43 int n, q; 44 scanf("%d%d", &n, &q); 45 for(int i = 1; i <= q; ++ i) { 46 int op, x = 0, y = 0; 47 scanf("%d", &op); 48 if(op == 1) { 49 scanf("%d%d", &x, &y); 50 y %= MOD; 51 y = (y + MOD) % MOD; 52 } 53 else if(2 <= op && op <= 5) { 54 scanf("%d", &x); 55 if(op != 5) { 56 x %= MOD; 57 x = (x + MOD) % MOD; 58 } 59 } 60 //cerr << op << " " << x << " " << y << endl; 61 que[i] = (Node){op, x, y}; 62 } 63 int mul = 1, add = 0, sum = 0; 64 int t; 65 scanf("%d", &t); 66 int Ans = 0, cnt = 0; 67 while(t --) { 68 int A, B; 69 scanf("%d%d", &A, &B); 70 //cerr << A << B << endl; 71 for(int i = 1; i <= q; ++ i) { 72 ++ cnt; 73 int id = (A + 1ll * i * B) % q + 1; 74 int op = que[id].op, x = que[id].x, y = que[id].y; 75 if(op == 1) { 76 int ry = 1ll * (y - add + MOD) * inv[mul] % MOD; 77 int d = hash::upd(x, ry, cnt); 78 sum += d; 79 if(sum >= MOD) sum -= MOD; 80 if(sum < 0) sum += MOD; 81 } 82 else if(op == 2) { 83 add += x; 84 if(add >= MOD) add -= MOD; 85 } 86 else if(op == 4 || (op == 3 && x == 0)) { 87 sum = 1ll * n * x % MOD; 88 add = 0, mul = 1; 89 hash::All = (x + MOD) % MOD; 90 hash::CLO = cnt; 91 } 92 else if(op == 3) { 93 mul = 1ll * mul * x % MOD; 94 add = 1ll * add * x % MOD; 95 } 96 else if(op == 5) { 97 int res = hash::query(x); 98 res = (1ll * res * mul + add) % MOD; 99 Ans += res; 100 if(Ans >= MOD) Ans -= MOD; 101 } 102 else { 103 int res = (1ll * sum * mul + 1ll * n * add) % MOD; 104 Ans += res; 105 if(Ans >= MOD) Ans -= MOD; 106 } 107 if(mul < 0) mul += MOD; 108 if(add < 0) add += MOD; 109 if(sum < 0) sum += MOD; 110 //cerr << sum << endl; 111 } 112 } 113 printf("%d\n", Ans); 114 }
SDOI2019 noisy party and embarrassment of the party
Construct a good question.
$ \ Lfloor \ frac {n} {p + 1} \ rfloor \ leq q $ can be introduced $ (p + 1) (q + 1)> n $.
Every enumerate the current figure smallest degree point $ x $, $ x $ and delete the $ x $ neighboring points.
Provided a total of $ Q $ views are deleted, apparently $ \ sum_ {i = 1} ^ q (d_i + 1) = n $.
For each enumerated $ X $ maximum degree of $ mxd $, we will be able to find a $ p = mxd $ configuration scheme.
It is $ \ sum_ {i = 1} ^ q (d_i + 1) \ leq mxd * q $.
We found little down can be shown that if $ p = mxd $ configuration scheme, meet $ (p + 1) (q + 1)> n $.
Is the configuration of the embodiment, when $ d_x = mxd $, the rest of all the current point in FIG.
Obviously it can be found in addition to the $ x $, $ y $ other points to meet the $ mxd \ leq d_y $.
Maintenance can use $ set $.
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct Edge{ 4 int u, v, Next; 5 } G[200010]; 6 int head[100010], tot; 7 int d[100010]; 8 struct Node{ 9 int D, x; 10 inline bool operator < (const Node& rhs) const{ 11 return D < rhs.D || (D == rhs.D && x < rhs.x); 12 } 13 }; 14 set<Node> S; 15 inline void add(int u, int v) { 16 G[++ tot] = (Edge){u, v, head[u]}; 17 head[u] = tot; 18 } 19 int ans1[100010], t1; 20 int ans2[100010], t2; 21 inline void solve() { 22 int n, m; 23 scanf("%d%d", &n, &m); 24 tot = 0; 25 for(int i = 1; i <= n; ++ i) { 26 head[i] = -1; 27 d[i] = 0; 28 } 29 for(int i = 1; i <= m; ++ i) { 30 int u, v; 31 scanf("%d%d", &u, &v); 32 add(u, v), add(v, u); 33 ++ d[u], ++ d[v]; 34 } 35 for(int i = 1; i <= n; ++ i) { 36 S.insert((Node){d[i], i}); 37 } 38 int mxd = 0, pos; 39 t1 = t2 = 0; 40 while(!S.empty()) { 41 set<Node> :: iterator t = S.begin(); 42 //cerr << "element " << t -> x << endl; 43 S.erase(t); 44 if(t -> D > mxd) { 45 mxd = t -> D; 46 pos = t1; 47 } 48 int x = t -> x; 49 ans2[++ t2] = x; 50 ans1[++ t1] = x; 51 for(int i = head[x]; i != -1; i = G[i].Next) { 52 t = S.find((Node){d[G[i].v], G[i].v}); 53 54 if(t == S.end()) continue; 55 //cerr << x << " " << G[i].v << endl; 56 int X = t -> x; 57 ans1[++ t1] = X; 58 S.erase(t); 59 for(int j = head[X]; j != -1; j = G[j].Next) { 60 set<Node> :: iterator it = S.find((Node){d[G[j].v], G[j].v}); 61 if(it == S.end()) continue; 62 S.erase(it); 63 S.insert((Node){-- d[G[j].v], G[j].v}); 64 } 65 } 66 } 67 printf("%d ", t1 - pos); 68 for(int i = pos + 1; i <= t1; ++ i) { 69 printf("%d ", ans1[i]); 70 } 71 puts(""); 72 printf("%d ", t2); 73 for(int i = 1; i <= t2; ++ i) { 74 printf("%d ", ans2[i]); 75 } 76 puts(""); 77 } 78 int main() { 79 int T; 80 scanf("%d", &T); 81 while(T --) { 82 solve(); 83 } 84 }