[关闭]
@yang12138 2023-05-12T02:31:12.000000Z 字数 63810 阅读 246

CPC Code Template

未分类


String

KMP

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. class KMP {
  4. private:
  5. static const int LEN = 100000 + 10;
  6. static int next[LEN];
  7. template<class T>
  8. static void GetNext(const T* const s, int n) {
  9. next[0] = -1;
  10. for (int i = 1; i < n; i++) {
  11. next[i] = next[i-1];
  12. while (next[i] >= 0 && s[next[i]+1] != s[i]) next[i] = next[next[i]];
  13. if (s[next[i]+1] == s[i]) next[i]++;
  14. }
  15. }
  16. public:
  17. // match t on s
  18. template<class T>
  19. static int Gao(const T* const s, int n, const T* const t, int m) {
  20. GetNext(t, m);
  21. int pos = -1, ans = 0;
  22. for (int i = 0; i < n; i++) {
  23. while (pos >= 0 && s[i] != t[pos+1]) pos = next[pos];
  24. if (s[i] == t[pos+1]) pos++;
  25. if (pos == m-1) return i - m + 1;
  26. }
  27. return -2;
  28. }
  29. };
  30. int KMP::next[KMP::LEN];
  31. int a[1000010], b[10010];
  32. int main() {
  33. int T;
  34. scanf("%d", &T);
  35. while (T--) {
  36. int n, m;
  37. scanf("%d%d", &n, &m);
  38. assert(n <= 100000);
  39. for (int i = 0; i < n; i++) scanf("%d", a+i);
  40. for (int i = 0; i < m; i++) scanf("%d", b+i);
  41. printf("%d\n", KMP::Gao(a, n, b, m)+1);
  42. }
  43. return 0;
  44. }

Manacher

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. class Manacher {
  5. public:
  6. static int Gao(const char* const str, int n) {
  7. int m = 0;
  8. t[m++] = '!';
  9. for (int i = 0; i < n; i++) {
  10. t[m++] = '@';
  11. t[m++] = str[i];
  12. }
  13. t[m++] = '@';
  14. int center = 0, radius = 0;
  15. ll ans = 0;
  16. int len = 0;
  17. for (int i = 0; i < m; i++) {
  18. if (i < center + radius)
  19. r[i] = min(r[2 * center - i], center + radius - i);
  20. while (t[i - r[i] - 1] == t[i + r[i] + 1]) r[i]++;
  21. if (i + r[i] > center + radius) center = i, radius = r[i];
  22. ans += (r[i] + 1) / 2;
  23. len = max(len, r[i]);
  24. }
  25. // return ans;
  26. return len;
  27. }
  28. private:
  29. static const int LEN = 2000000 + 10;
  30. static char t[LEN];
  31. static int r[LEN];
  32. };
  33. char Manacher::t[Manacher::LEN];
  34. int Manacher::r[Manacher::LEN];
  35. char in[800010];
  36. int main() {
  37. scanf("%s", in);
  38. printf("%d\n", Manacher::Gao(in, strlen(in)));
  39. return 0;
  40. }

Suffix Array

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. struct SA {
  5. static const int N = 1e5 + 10;
  6. // a_i >= 0
  7. void GetSA(const int* a, int n) {
  8. int up = 0;
  9. for (int i = 0; i < n; i++) up = max(up, a[i]);
  10. up++;
  11. int *rk1 = rk[0], *rk2 = rk[1];
  12. std::fill(cnt, cnt + up, 0);
  13. for (int i = 0; i < n; i++) cnt[rk1[i] = a[i]]++;
  14. for (int i = 0; i+1 < up; i++) cnt[i+1] += cnt[i];
  15. for (int i = n - 1; i >= 0; i--) sa[--cnt[rk1[i]]] = i;
  16. for (int d = 1; d <= n; d <<= 1) {
  17. int p = 0;
  18. for (int i = n - d; i < n; i++) id[p++] = i;
  19. for (int i = 0; i < n; i++) if (sa[i] >= d) id[p++] = sa[i] - d;
  20. std::fill(cnt, cnt + up, 0);
  21. for (int i = 0; i < n; i++) cnt[rk2[i] = rk1[id[i]]]++;
  22. for (int i = 0; i+1 < up; i++) cnt[i+1] += cnt[i];
  23. for (int i = n - 1; i >= 0; i--) sa[--cnt[rk2[i]]] = id[i];
  24. rk2[sa[0]] = 0;
  25. for (int i = 1; i < n; i++) {
  26. if (sa[i-1] + d < n && sa[i] + d < n && rk1[sa[i-1]] == rk1[sa[i]]
  27. && rk1[sa[i-1]+d] == rk1[sa[i]+d])
  28. rk2[sa[i]] = rk2[sa[i-1]];
  29. else rk2[sa[i]] = rk2[sa[i-1]] + 1;
  30. }
  31. swap(rk1, rk2);
  32. up = n;
  33. if (rk2[sa[n-1]] == n) break;
  34. }
  35. height[0] = 0;
  36. for (int i = 0, p = 0; i < n; i++) {
  37. if (rk1[i] == 0) continue;
  38. int j = sa[rk1[i]-1];
  39. while (i + p < n && j + p < n && a[i+p] == a[j+p]) p++;
  40. height[rk1[i]] = p;
  41. p = max(0, p-1);
  42. }
  43. }
  44. void GetSA(const char* s) {
  45. int n = strlen(s);
  46. int* a = new int[n];
  47. for (int i = 0; i < n; i++) a[i] = s[i];
  48. GetSA(a, n);
  49. }
  50. int cnt[N], id[N];
  51. int sa[N]; // index from 0 ~ n-1
  52. int rk[2][N]; // index from 0 ~ n-1
  53. int height[N]; // index from 1 ~ n-1, largest common prefix of suffix_sa[i] and suffix_sa[i-1]
  54. } sagetter;
  55. void solve() {
  56. string s;
  57. cin >> s;
  58. sagetter.GetSA(s.c_str());
  59. int* sa = sagetter.sa;
  60. int* h = sagetter.height;
  61. for (int i = 0; i < s.size(); i++) {
  62. printf("sa %d string %s height %d\n", sa[i], s.substr(sa[i], s.size()).c_str(), h[i]);
  63. }
  64. }
  65. int main() {
  66. int T = 1;
  67. // scanf("%d", &T);
  68. while (T--) solve();
  69. return 0;
  70. }

AC-AutoMachine

  1. // codeforeces 633C
  2. // link: https://codeforces.com/problemset/problem/633/C
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. struct Node {
  6. static const int SIZE = 26;
  7. int ch[SIZE];
  8. int val, fail, dep;
  9. int endpoint;
  10. Node() {
  11. fail = 0, endpoint = -1;
  12. memset(ch, 0, sizeof(ch));
  13. }
  14. };
  15. struct ACAuto {
  16. static const int N = 1e6+10;
  17. Node t[N];
  18. int counter = 1;
  19. // A - Z, a - z
  20. static int transform(char ch) {
  21. if (ch >= 'A' && ch <= 'Z') return ch - 'A';
  22. return ch - 'a';
  23. }
  24. void Insert(const char* s, int index) {
  25. int root = 0;
  26. for (int i = 0; s[i]; i++) {
  27. int v = transform(s[i]);
  28. if (!t[root].ch[v]) t[root].ch[v] = counter++;
  29. root = t[root].ch[v];
  30. t[root].val = v;
  31. t[root].dep = i + 1;
  32. }
  33. t[root].endpoint = index;
  34. }
  35. void BFS() {
  36. typedef pair<int, int> pii;
  37. queue<pii> que;
  38. que.push(pii(0, 0));
  39. while (!que.empty()) {
  40. pii p = que.front(); que.pop();
  41. int u = p.first, pre = p.second;
  42. for (int i = 0; i < Node::SIZE; i++) {
  43. if (t[u].ch[i]) que.push(pii(t[u].ch[i], u));
  44. }
  45. if (u == 0) continue;
  46. if (t[u].dep == 1) {
  47. t[u].fail = 0;
  48. continue;
  49. }
  50. int fail = t[pre].fail;
  51. int val = t[u].val;
  52. while (fail && t[fail].ch[val] == 0) fail = t[fail].fail;
  53. t[u].fail = t[fail].ch[val];
  54. }
  55. }
  56. void Init(const vector<const char*>& stringlist) {
  57. for (int i = 0; i < stringlist.size(); i++) Insert(stringlist[i], i);
  58. BFS();
  59. }
  60. int* Solve(const char* s) {
  61. int root = 0, n = strlen(s), pos = 0;
  62. int* dp = new int[n + 1];
  63. memset(dp, -1, sizeof(int)*(n+1));
  64. dp[0] = 0;
  65. for (int i = 0; i < n; i++) {
  66. int v = transform(s[i]);
  67. while (pos && t[pos].ch[v] == 0) pos = t[pos].fail;
  68. pos = t[pos].ch[v];
  69. // printf("pos[%d]=%d\n", i+1, pos);
  70. {
  71. int fail = pos;
  72. while (fail) {
  73. if (t[fail].endpoint >= 0 && dp[i+1-t[fail].dep] >= 0) {
  74. dp[i+1] = t[fail].endpoint;
  75. break;
  76. }
  77. fail = t[fail].fail;
  78. }
  79. }
  80. // printf("dp[%d]=%d\n\n", i+1, dp[i+1]);
  81. }
  82. assert(dp[n] >= 0);
  83. return dp;
  84. }
  85. } acauto;
  86. char buffer[1000000 + 100000 + 10];
  87. char text[10010];
  88. int pos[100010];
  89. int len[100010];
  90. void DFS(int index, const int* dp) {
  91. if (index == 0) return ;
  92. // printf("index: %d, dp: %d, pos: %d, len: %d\n", index, dp[index], pos[dp[index]], len[dp[index]]);
  93. DFS(index - len[dp[index]], dp);
  94. printf("%s ", buffer + pos[dp[index]]);
  95. }
  96. void solve() {
  97. int n;
  98. scanf("%d%s", &n, text);
  99. vector<const char*> stringlist;
  100. int m;
  101. scanf("%d", &m);
  102. stringlist.reserve(m);
  103. for (int i = 0; i < m; i++) {
  104. scanf("%s", buffer+pos[i]);
  105. stringlist.push_back(buffer+pos[i]);
  106. len[i] = strlen(buffer+pos[i]);
  107. pos[i+1] = pos[i] + len[i] + 1;
  108. reverse(buffer+pos[i], buffer+pos[i]+len[i]);
  109. }
  110. acauto.Init(stringlist);
  111. // cout << "init succ" << endl;
  112. const int* dp = acauto.Solve(text);
  113. // cout << "solve succ" << endl;
  114. for (int i = 0; i < m; i++)
  115. reverse(buffer+pos[i], buffer+pos[i]+len[i]);
  116. DFS(n, dp);
  117. printf("\n");
  118. }
  119. int main() {
  120. solve();
  121. return 0;
  122. }

String Hash

  1. // https://www.luogu.com.cn/problem/P3370
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. template <int P, int MOD>
  5. struct StringHash {
  6. public:
  7. StringHash() {}
  8. StringHash(const char* s, int n) { Init(s, n); }
  9. void Init(const char* s, int n) {
  10. assert(1LL * P * INV % MOD == 1);
  11. inv = hash = vector<int>(n);
  12. int pw = 1;
  13. for (int i = 0; i < n; i++) {
  14. hash[i] = ((i ? hash[i-1] : 0) + 1LL * pw * (int)s[i]) % MOD;
  15. inv[i] = i ? (1LL * inv[i-1] * INV % MOD) : 1;
  16. pw = 1LL * pw * P % MOD;
  17. }
  18. }
  19. int GetHash(int l, int r) const {
  20. assert(r >= l - 1 && l >= 0 && r < (int)hash.size());
  21. if (l > r) return 0;
  22. if (l == 0) return hash[r];
  23. return 1LL * (hash[r] - hash[l-1] + MOD) * inv[l] % MOD;
  24. }
  25. private:
  26. constexpr static int PowMod(int a, int n) {
  27. int ans = 1;
  28. while (n) {
  29. if (n & 1) ans = 1LL * ans * a % MOD;
  30. a = 1LL * a * a % MOD;
  31. n >>= 1;
  32. }
  33. return ans;
  34. }
  35. constexpr static int INV = PowMod(P, MOD - 2);
  36. vector<int> hash, inv;
  37. };
  38. typedef StringHash<1009, 1000000007> Hasher;
  39. // typedef StringHash<2003, 1000000009> Hasher2;
  40. const int N = 1e5 + 10;
  41. char buf[N];
  42. int main() {
  43. int n;
  44. scanf("%d", &n);
  45. set<int> st;
  46. for (int i = 0; i < n; i++) {
  47. scanf("%s", buf);
  48. Hasher h(buf, strlen(buf));
  49. st.insert(h.GetHash(0, strlen(buf)-1));
  50. }
  51. printf("%d\n", (int)st.size());
  52. return 0;
  53. }

Min Representation

  1. // http://acm.hdu.edu.cn/showproblem.php?pid=3374
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const int N = 1e6+10;
  7. char s[N];
  8. typedef std::function<bool(char, char)> LessFunc;
  9. void solve(LessFunc leq) {
  10. int n = strlen(s);
  11. int i = 0, j = 1, k = 0;
  12. while (k < n) {
  13. // printf("i %d, j %d, k %d\n", i, j, k);
  14. if (leq(s[(j+k)%n], s[(i+k)%n])) {
  15. if (i+k+1 >= n) break;
  16. (i += k+1) %= n;
  17. k = 0;
  18. } else if (leq(s[(i+k)%n], s[(j+k)%n])) {
  19. if (j+k+1 >= n) break;
  20. (j += k+1) %= n;
  21. k = 0;
  22. } else {
  23. k++;
  24. }
  25. if (i == j) {
  26. (j += 1) %= n;
  27. if (j == 0) break;
  28. }
  29. }
  30. printf("%d %d", i+1, n / (k == n ? abs(i-j) : n));
  31. }
  32. bool solve() {
  33. if (scanf("%s", s) == 1) {
  34. solve([](char a, char b) { return a < b; });
  35. printf(" ");
  36. solve([](char a, char b) { return a > b; });
  37. printf("\n");
  38. return true;
  39. }
  40. return false;
  41. }
  42. int main() {
  43. while (solve());
  44. return 0;
  45. }

Network Flow

Max Flow

  1. // author: yang12138
  2. // https://atcoder.jp/contests/abc274/tasks/abc274_g
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef pair<int, int> pii;
  7. static const int INF = 1e9;
  8. struct NetFlow {
  9. struct Edge {
  10. int to, cap, rev;
  11. Edge(int to, int cap, int rev) : to(to), cap(cap), rev(rev) {}
  12. };
  13. vector<vector<Edge>> G;
  14. vector<int> iter, level;
  15. NetFlow(int V) : G(V), iter(V), level(V) {}
  16. void AddEdge(int u, int v, int cap) {
  17. G[u].push_back(Edge(v, cap, (int)G[v].size()));
  18. G[v].push_back(Edge(u, 0, (int)G[u].size()-1));
  19. }
  20. void BFS(int s) {
  21. fill(level.begin(), level.end(), -1);
  22. level[s]=0;
  23. queue<int> que;
  24. que.push(s);
  25. while (!que.empty()) {
  26. int v = que.front();
  27. que.pop();
  28. for(int i = 0; i < G[v].size(); i++) {
  29. Edge& e=G[v][i];
  30. if(level[e.to] < 0 && e.cap > 0)
  31. level[e.to] = level[v] + 1, que.push(e.to);
  32. }
  33. }
  34. }
  35. int DFS(int s, int t, int f) {
  36. if (s == t) return f;
  37. for (int& i = iter[s]; i < (int)G[s].size(); i++) {
  38. Edge& e = G[s][i];
  39. if (level[s] < level[e.to] && e.cap > 0) {
  40. int d = DFS(e.to, t, min(f, e.cap));
  41. if (d > 0) {
  42. e.cap -= d, G[e.to][e.rev].cap += d;
  43. return d;
  44. }
  45. }
  46. }
  47. return 0;
  48. }
  49. int MaxFlow(int s, int t) {
  50. int flow = 0;
  51. while (BFS(s), level[t] >= 0) {
  52. fill(iter.begin(), iter.end(), 0);
  53. int f = 0;
  54. while(f = DFS(s,t,INF)) flow += f;
  55. }
  56. return flow;
  57. }
  58. };
  59. const int N = 305;
  60. char str[N][N];
  61. int up[N][N], lef[N][N];
  62. void solve() {
  63. int n, m;
  64. scanf("%d%d", &n, &m);
  65. auto GetNum = [&](int i, int j) { return (i - 1) * m + j; };
  66. int s = 0, t = 2 * n * m + 1;
  67. NetFlow nf(t + 1);
  68. for (int i = 1; i <= n; i++) {
  69. scanf("%s", str[i] + 1);
  70. for (int j = 1; j <= m; j++) {
  71. if (str[i][j] == '.') {
  72. up[i][j] = (i - 1 >= 1 && str[i-1][j] == '.') ? up[i-1][j] : i;
  73. lef[i][j] = (j - 1 >= 1 && str[i][j-1] == '.') ? lef[i][j-1] : j;
  74. nf.AddEdge(GetNum(up[i][j], j), GetNum(i, lef[i][j]) + n * m, INF);
  75. // printf("%d %d up %d lef %d\n", i, j, up[i][j], lef[i][j]);
  76. }
  77. nf.AddEdge(s, GetNum(i, j), 1);
  78. nf.AddEdge(GetNum(i, j) + n * m, t, 1);
  79. }
  80. }
  81. printf("%d\n", nf.MaxFlow(s, t));
  82. }
  83. int main() {
  84. int T = 1;
  85. // scanf("%d", &T);
  86. while (T--) solve();
  87. return 0;
  88. }

Min Cost Flow

  1. // http://codeforces.com/contest/1510/problem/B
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. struct Edge {
  7. int to, cap, cost, rev;
  8. Edge(int to, int cap, int cost, int rev) : to(to), cap(cap), cost(cost), rev(rev) {}
  9. };
  10. struct CostFlow {
  11. static const int V = (1 << 11) + 10;
  12. static const int INF = 1e9;
  13. CostFlow(): n_(0) {}
  14. void Reset() {
  15. for (int i = 0; i < n_; i++) G[i].clear();
  16. n_ = 0;
  17. }
  18. void AddEdge(int from, int to, int cap, int cost) {
  19. G[from].push_back(Edge(to, cap, cost, G[to].size()));
  20. G[to].push_back(Edge(from, 0, -cost, G[from].size() - 1));
  21. }
  22. void SetMax(int n) { n_ = n + 1; }
  23. vector<Edge> G[V];
  24. int h[V], dist[V];
  25. int preV[V], preE[V];
  26. int n_;
  27. // 初始边权有正有负时不能用
  28. int MinCostFlow(const int s, const int t, int max_flow, int* real_flow = nullptr) {
  29. priority_queue<pii, vector<pii>, greater<pii> > que;
  30. int res = 0;
  31. memset(h, 0, sizeof(h[0])*n_);
  32. while (max_flow) {
  33. // printf("max_flow %d\n", max_flow);
  34. for (int i = 0; i < n_; i++) dist[i] = INF;
  35. dist[s] = 0;
  36. que.push(pii(0, s));
  37. while (!que.empty()) {
  38. pii p = que.top();
  39. que.pop();
  40. int v = p.second;
  41. if (dist[v] < p.first) continue;
  42. for (int i = 0; i < G[v].size(); i++) {
  43. const Edge& e = G[v][i];
  44. if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
  45. dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
  46. preV[e.to] = v, preE[e.to] = i;
  47. que.push(pii(dist[e.to], e.to));
  48. }
  49. }
  50. }
  51. if (dist[t] == INF) return res;
  52. for (int i = 0; i < n_; i++) h[i] += dist[i];
  53. int cur_flow = max_flow;
  54. for (int i = t; i != s; i = preV[i]) {
  55. cur_flow = min(cur_flow, G[preV[i]][preE[i]].cap);
  56. }
  57. // printf("cur_flow %d dist[t]\n", cur_flow, dist[t]);
  58. if (real_flow) *real_flow += cur_flow;
  59. max_flow -= cur_flow;
  60. res += cur_flow * h[t];
  61. for (int i = t; i != s; i = preV[i]) {
  62. Edge& e = G[preV[i]][preE[i]];
  63. e.cap -= cur_flow, G[i][e.rev].cap += cur_flow;
  64. }
  65. }
  66. return res;
  67. }
  68. int MinCostMaxFlow(const int s, const int t, int* real_flow = nullptr) {
  69. return MinCostFlow(s, t, INF, real_flow);
  70. }
  71. const vector<Edge>* GetG() { return G; }
  72. } min_cost_flow;
  73. void solve() {
  74. int d, n;
  75. scanf("%d%d", &d, &n);
  76. char buffer[20];
  77. vector<int> st(n);
  78. for (int i = 0; i < n; i++) {
  79. scanf("%s", buffer);
  80. for (int j = 0; j < d; j++) {
  81. if (buffer[j] == '1') st[i] |= (1 << j);
  82. }
  83. }
  84. sort(st.begin(), st.end());
  85. vector<int> bits(1 << d);
  86. vector<int> lastb(1 << d);
  87. for (int i = 1; i < (1 << d); i++) {
  88. bits[i] = bits[i/2] + (i&1);
  89. if (i&1) lastb[i] = 0;
  90. else lastb[i] = lastb[i/2]+1;
  91. }
  92. int s = 0, t = 2*n+1;
  93. for (int i = 0; i < n; i++) {
  94. for (int j = 0; j < i; j++) {
  95. if ((st[i] | st[j]) == st[i]) {
  96. min_cost_flow.AddEdge(j+1, i+1+n, 1, -bits[st[j]]);
  97. }
  98. }
  99. min_cost_flow.AddEdge(s, i+1, 1, 0);
  100. min_cost_flow.AddEdge(i+1+n, t, 1, -1);
  101. }
  102. vector<int> in(1 << d, 0);
  103. vector<int> vis(1 << d, 0);
  104. vector<int> nex(1 << d);
  105. int bs = 0;
  106. for (auto i: st) in[i] = 1, bs += bits[i];
  107. min_cost_flow.SetMax(t);
  108. int flow = 0;
  109. int cost = min_cost_flow.MinCostMaxFlow(s, t, &flow);
  110. cost += n-1 + bs;
  111. for (int i = 1; i <= n; i++) {
  112. for (const Edge& e : min_cost_flow.GetG()[i]) {
  113. if (e.to >= n+1 && e.to <= 2*n && e.cap == 0) {
  114. nex[st[i-1]] = st[e.to-n-1];
  115. break;
  116. }
  117. }
  118. }
  119. vector<char> ans;
  120. int reset = 0, rcnt = 0;
  121. for (int i = 1; i < (1 << d); i++) {
  122. if (!in[i]) continue;
  123. if (vis[i]) continue;
  124. if (reset) ans.push_back('R'), rcnt++;
  125. int pre = 0, cur = i;
  126. while (cur) {
  127. vis[cur] = 1;
  128. int tmp = (pre ^ cur);
  129. while (tmp) {
  130. ans.push_back('0' + lastb[tmp]);
  131. tmp ^= (1 << lastb[tmp]);
  132. }
  133. pre = cur, cur = nex[cur];
  134. }
  135. reset = 1;
  136. }
  137. /*
  138. printf("reset cnt: %d, flow: %d\n", rcnt, flow);
  139. printf("cost: %d, ans size: %d\n", cost, int(ans.size()));
  140. */
  141. printf("%d\n", ans.size());
  142. for (auto i: ans) printf("%c ", i);
  143. printf("\n");
  144. assert(rcnt == n-1-flow);
  145. assert(cost == ans.size());
  146. }
  147. int main() {
  148. int T = 1;
  149. // scanf("%d", &T);
  150. while (T--) solve();
  151. }

Global Min Cut

  1. // https://acm.hdu.edu.cn/showproblem.php?pid=6081
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const int N = 3005;
  7. const int INF = 1e9;
  8. struct Edge {
  9. int u, v, w;
  10. void scan() { scanf("%d%d%d", &u, &v, &w); }
  11. };
  12. struct DisjointSet {
  13. int fa[N], n;
  14. void Init(int n) {
  15. this->n = n;
  16. for (int i = 1; i <= n; i++) fa[i] = -1;
  17. }
  18. int FindFa(int u) {
  19. return (fa[u] < 0) ? u : (fa[u] = FindFa(fa[u]));
  20. }
  21. bool Merge(int u, int v) {
  22. u = FindFa(u), v = FindFa(v);
  23. if (u == v) return true;
  24. if (fa[u] + fa[v] == -n) return false;
  25. fa[u] += fa[v];
  26. fa[v] = u;
  27. return true;
  28. }
  29. } ds;
  30. bool solve() {
  31. int n, m;
  32. if (scanf("%d%d", &n, &m) != 2) return false;
  33. vector<Edge> edges(m);
  34. for (auto& edge : edges) edge.scan();
  35. int ans = INF;
  36. int unchange = 0;
  37. const int LIMIT = 2000;
  38. do {
  39. random_shuffle(edges.begin(), edges.end());
  40. ds.Init(n);
  41. bool flag = false;
  42. for (const auto& edge : edges) {
  43. if (!ds.Merge(edge.u, edge.v)) {
  44. flag = true;
  45. break;
  46. }
  47. }
  48. if (!flag) {
  49. ans = 0;
  50. break;
  51. }
  52. int tans = 0;
  53. for (const auto& edge : edges) {
  54. if (ds.FindFa(edge.u) != ds.FindFa(edge.v)) {
  55. tans += edge.w;
  56. }
  57. }
  58. if (ans <= tans) unchange++;
  59. else ans = tans, unchange = 0;
  60. // printf("tans %d, ans %d\n", tans, ans);
  61. } while (unchange <= LIMIT);
  62. printf("%d\n", ans);
  63. return true;
  64. }
  65. int main() {
  66. while (solve());
  67. return 0;
  68. }

KM Algorithm

  1. // https://acm.hdu.edu.cn/showproblem.php?pid=2255
  2. // https://acm.hdu.edu.cn/showproblem.php?pid=6346
  3. // KM algorithm
  4. // MaxWeightMatch of bipartite graph
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7. typedef long long ll;
  8. const int N = 505;
  9. const int INF = 2e9;
  10. int A[N], B[N], slack[N];
  11. int w[N][N];
  12. // all rig
  13. int match[N], repl[N];
  14. bool vis[N];
  15. int nx, ny;
  16. ll KM() {
  17. assert(nx >= 1 && ny >= 1 && nx <= ny);
  18. std::fill(match + 1, match + ny + 1, -1);
  19. for(int x = 1; x <= nx; x++) {
  20. int currig = 0;
  21. match[currig] = x;
  22. std::fill(vis, vis + ny + 1, false);
  23. std::fill(slack + 1, slack + ny + 1, INF);
  24. while (match[currig] != -1) {
  25. vis[currig] = true;
  26. int curlef = match[currig], nexrig = -1;
  27. ll d = INF;
  28. for (int y = 1; y <= ny; y++) {
  29. if (!vis[y]) {
  30. ll t = A[curlef] + B[y] - w[curlef][y];
  31. if (t < slack[y]) slack[y] = t, repl[y] = currig;
  32. if (slack[y] < d) d = slack[y], nexrig = y;
  33. }
  34. }
  35. for (int y = 0; y <= ny; y++) {
  36. if (vis[y]) A[match[y]] -= d, B[y] += d;
  37. else slack[y] -= d;
  38. }
  39. currig = nexrig;
  40. }
  41. while (currig) {
  42. int nexrig = repl[currig];
  43. match[currig] = match[nexrig];
  44. currig = nexrig;
  45. }
  46. }
  47. ll ans = 0;
  48. for (int i = 1; i <= ny; i++) {
  49. if (match[i] > 0) ans += B[i] + A[match[i]];
  50. }
  51. return ans;
  52. }
  53. void solve(int cas) {
  54. int n;
  55. scanf("%d", &n);
  56. for (int i = 1; i <= n; i++) {
  57. for (int j = 1; j <= n; j++) {
  58. scanf("%d", &w[i][j]);
  59. w[i][j] *= -1;
  60. }
  61. }
  62. nx = ny = n;
  63. printf("Case #%d: %lld\n", cas, -KM());
  64. }
  65. int main() {
  66. int T, t = 0;
  67. scanf("%d", &T);
  68. while (T--) solve(++t);
  69. return 0;
  70. }

Data Structure

  1. // https://www.luogu.com.cn/problem/P1501
  2. // https://www.luogu.com.cn/problem/P2147
  3. // https://www.luogu.com.cn/problem/P3690
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. typedef long long ll;
  7. typedef pair<int, int> pii;
  8. const int N = 1e5+10;
  9. const int MOD = 51061;
  10. int ch[N][2], f[N];
  11. struct Value {
  12. int mul = 0, add = 0, val = 0, sum = 0, sz = 0, tag = 0;
  13. Value() {}
  14. Value(int mul, int add, int tag = 0): mul(mul), add(add), tag(tag) {}
  15. void PushDown(Value& rhs) const {
  16. if (mul != 1) {
  17. rhs.mul = 1LL * rhs.mul * mul % MOD;
  18. rhs.add = 1LL * rhs.add * mul % MOD;
  19. rhs.val = 1LL * rhs.val * mul % MOD;
  20. rhs.sum = 1LL * rhs.sum * mul % MOD;
  21. }
  22. if (add) {
  23. (rhs.add += add) %= MOD;
  24. (rhs.val += add) %= MOD;
  25. (rhs.sum += 1LL * rhs.sz * add % MOD) %= MOD;
  26. }
  27. if (tag) rhs.tag ^= 1;
  28. }
  29. void PushUp(const Value& lhs, const Value& rhs) {
  30. sz = lhs.sz + rhs.sz + 1;
  31. sum = (lhs.sum + rhs.sum + val) % MOD;
  32. }
  33. void Reset() {
  34. mul = 1, add = 0, tag = 0;
  35. }
  36. } val[N];
  37. int Get(int x) { return ch[f[x]][1] == x; }
  38. bool IsSplayRoot(int x) { return ch[f[x]][0] != x && ch[f[x]][1] != x; }
  39. void PushDown(int x) {
  40. if (val[x].tag) swap(ch[x][0], ch[x][1]);
  41. if (ch[x][0]) val[x].PushDown(val[ch[x][0]]);
  42. if (ch[x][1]) val[x].PushDown(val[ch[x][1]]);
  43. val[x].Reset();
  44. }
  45. void PushUp(int x) { val[x].PushUp(val[ch[x][0]], val[ch[x][1]]); }
  46. void Update(int x) { if (!IsSplayRoot(x)) Update(f[x]); PushDown(x); }
  47. void Rotate(int x) {
  48. assert(f[x]);
  49. int y = f[x], k = Get(x);
  50. // link y and ch[x][!k]
  51. if (ch[x][!k]) f[ch[x][!k]] = y;
  52. ch[y][k] = ch[x][!k];
  53. // link f[y] and x
  54. if (!IsSplayRoot(y)) ch[f[y]][Get(y)] = x;
  55. f[x] = f[y];
  56. // link x and y
  57. ch[x][!k] = y, f[y] = x;
  58. PushUp(y), PushUp(x);
  59. }
  60. void Splay(int x) {
  61. Update(x);
  62. for (int fa = f[x]; !IsSplayRoot(x); fa = f[x]) {
  63. if (!IsSplayRoot(fa) && !IsSplayRoot(f[fa]))
  64. Rotate(Get(fa) == Get(x) ? fa : x);
  65. Rotate(x);
  66. }
  67. }
  68. int Access(int x) {
  69. int p = 0;
  70. while (x) {
  71. Splay(x), ch[x][1] = p, PushUp(x);
  72. p = x, x = f[x];
  73. }
  74. return p;
  75. }
  76. void MakeRoot(int x) { val[Access(x)].tag ^= 1; }
  77. void Link(int x, int y) { MakeRoot(x), Splay(x), f[x] = y; }
  78. void Split(int x, int y) { MakeRoot(x), Access(y), Splay(x); }
  79. void Cut(int x, int y) { Split(x, y), Splay(y), ch[y][0] = f[x] = 0; }
  80. int FindRoot(int x) {
  81. Access(x), Splay(x);
  82. while (ch[x][0]) PushDown(x), x = ch[x][0];
  83. Splay(x);
  84. return x;
  85. }
  86. void solve() {
  87. int n, q;
  88. scanf("%d%d", &n, &q);
  89. for (int i = 1; i <= n; i++) {
  90. val[i].mul = val[i].val = val[i].sz = val[i].sum = 1;
  91. }
  92. for (int i = 1; i < n; i++) {
  93. int u, v;
  94. scanf("%d%d", &u, &v);
  95. Link(u, v);
  96. }
  97. char s[10];
  98. while (q--) {
  99. int u1, v1, u2, v2, c;
  100. scanf("%s%d%d", s, &u1, &v1);
  101. if (s[0] == '+') {
  102. scanf("%d", &c);
  103. Split(u1, v1);
  104. Value(1, c).PushDown(val[u1]);
  105. } else if (s[0] == '-') {
  106. scanf("%d%d", &u2, &v2);
  107. Cut(u1, v1);
  108. Link(u2, v2);
  109. } else if (s[0] == '*') {
  110. scanf("%d", &c);
  111. Split(u1, v1);
  112. Value(c, 0).PushDown(val[u1]);
  113. } else {
  114. Split(u1, v1);
  115. printf("%d\n", val[u1].sum);
  116. }
  117. }
  118. }
  119. int main() {
  120. int T = 1;
  121. // scanf("%d", &T);
  122. while (T--) solve();
  123. return 0;
  124. }
  1. // https://loj.ac/p/2230
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const int N = 1e5+10;
  7. int ch[N][2], f[N];
  8. struct Value {
  9. int tag = 0;
  10. int splay_size = 0, subtree_size = 0, virtualson_size = 0;
  11. Value() {}
  12. void PushDown(Value& rhs) const {
  13. if (tag) rhs.tag ^= 1;
  14. }
  15. void PushUp(const Value& lhs, const Value& rhs) {
  16. splay_size = lhs.splay_size + rhs.splay_size + 1;
  17. subtree_size = lhs.subtree_size + rhs.subtree_size + 1 + virtualson_size;
  18. }
  19. void Reset() { tag = 0; }
  20. } val[N];
  21. int Get(int x) { return ch[f[x]][1] == x; }
  22. bool IsSplayRoot(int x) { return ch[f[x]][0] != x && ch[f[x]][1] != x; }
  23. void PushDown(int x) {
  24. if (val[x].tag) swap(ch[x][0], ch[x][1]);
  25. if (ch[x][0]) val[x].PushDown(val[ch[x][0]]);
  26. if (ch[x][1]) val[x].PushDown(val[ch[x][1]]);
  27. val[x].Reset();
  28. }
  29. void PushUp(int x) { val[x].PushUp(val[ch[x][0]], val[ch[x][1]]); }
  30. void Update(int x) { if (!IsSplayRoot(x)) Update(f[x]); PushDown(x); }
  31. void Rotate(int x) {
  32. assert(f[x]);
  33. int y = f[x], k = Get(x);
  34. // link y and ch[x][!k]
  35. if (ch[x][!k]) f[ch[x][!k]] = y;
  36. ch[y][k] = ch[x][!k];
  37. // link f[y] and x
  38. if (!IsSplayRoot(y)) ch[f[y]][Get(y)] = x;
  39. f[x] = f[y];
  40. // link x and y
  41. ch[x][!k] = y, f[y] = x;
  42. PushUp(y), PushUp(x);
  43. }
  44. void Splay(int x) {
  45. Update(x);
  46. for (int fa = f[x]; !IsSplayRoot(x); fa = f[x]) {
  47. if (!IsSplayRoot(fa) && !IsSplayRoot(f[fa]))
  48. Rotate(Get(fa) == Get(x) ? fa : x);
  49. Rotate(x);
  50. }
  51. }
  52. int Access(int x) {
  53. int p = 0;
  54. while (x) {
  55. Splay(x);
  56. val[x].virtualson_size += val[ch[x][1]].subtree_size - val[p].subtree_size;
  57. ch[x][1] = p, PushUp(x);
  58. p = x, x = f[x];
  59. }
  60. return p;
  61. }
  62. void MakeRoot(int x) { val[Access(x)].tag ^= 1; }
  63. void Link(int x, int y) {
  64. MakeRoot(x), Splay(x);
  65. MakeRoot(y), Splay(y);
  66. f[x] = y, val[y].virtualson_size += val[x].subtree_size;
  67. }
  68. void Split(int x, int y) { MakeRoot(x), Access(y), Splay(x); }
  69. void Cut(int x, int y) { Split(x, y), Splay(y), ch[y][0] = f[x] = 0; }
  70. int FindRoot(int x) {
  71. Access(x), Splay(x);
  72. while (ch[x][0]) PushDown(x), x = ch[x][0];
  73. Splay(x);
  74. return x;
  75. }
  76. int GetTreeSize(int x) {
  77. MakeRoot(x), Splay(x);
  78. return val[x].subtree_size;
  79. }
  80. void solve() {
  81. int n, q;
  82. scanf("%d%d", &n, &q);
  83. for (int i = 1; i <= n; i++) val[i].subtree_size = 1;
  84. while (q--) {
  85. char op[4];
  86. int x, y;
  87. scanf("%s%d%d", op, &x, &y);
  88. if (op[0] == 'A') {
  89. Link(x, y);
  90. } else {
  91. Cut(x, y);
  92. printf("%lld\n", 1LL * GetTreeSize(x) * GetTreeSize(y));
  93. Link(x, y);
  94. }
  95. }
  96. }
  97. int main() {
  98. int T = 1;
  99. // scanf("%d", &T);
  100. while (T--) solve();
  101. return 0;
  102. }

Pairing Heap

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. template <typename T>
  4. struct PairingHeap {
  5. public:
  6. static const int N = 3e5+10;
  7. PairingHeap() { Reset(N - 1); }
  8. void Reset(int n) {
  9. root = 0;
  10. std::memset(val, sizeof(val[0]) * (n + 1), 0);
  11. std::fill(son, son + n + 1, 0);
  12. std::fill(pre, pre + n + 1, 0);
  13. std::fill(bro, bro + n + 1, 0);
  14. }
  15. const T& GetVal(int u) const { return val[u]; }
  16. bool InHeap(int u) const { return u == root || pre[u] != 0; }
  17. bool Empty() const { return root ? false : true; }
  18. T Top() const {
  19. assert(!Empty());
  20. return val[root];
  21. }
  22. void Push(int u, T x) {
  23. assert(son[u] == 0 && pre[u] == 0 && bro[u] == 0);
  24. val[u] = x;
  25. root = Merge(root, u);
  26. }
  27. void Pop() {
  28. assert(!Empty());
  29. int tmp = Merges(son[root]);
  30. ResetNode(root);
  31. root = tmp;
  32. }
  33. void Update(int u, T x) {
  34. assert(x < val[u]);
  35. val[u] = x;
  36. if (u == root) return ;
  37. assert(pre[u]);
  38. if (son[pre[u]] == u) son[pre[u]] = bro[u];
  39. else bro[pre[u]] = bro[u];
  40. if (bro[u]) pre[bro[u]] = pre[u];
  41. root = Merge(root, u);
  42. }
  43. private:
  44. void ResetNode(int u) { son[u] = pre[u] = bro[u] = 0; }
  45. void MakeRoot(int u) { pre[u] = bro[u] = 0; }
  46. int Merge(int u, int v) {
  47. MakeRoot(u), MakeRoot(v);
  48. if (u == 0 || v == 0) return u ^ v;
  49. if (val[u] > val[v]) swap(u, v);
  50. bro[v] = son[u];
  51. if (son[u]) pre[son[u]] = v;
  52. son[u] = v;
  53. pre[v] = u;
  54. return u;
  55. }
  56. int Merges(int u) {
  57. if (u == 0) return 0;
  58. int v = bro[u], w = bro[v];
  59. return Merge(Merge(u, v), Merges(w));
  60. }
  61. T val[N];
  62. int son[N], pre[N], bro[N], root;
  63. };
  64. int main() {
  65. return 0;
  66. }

Skip List

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. struct SkipListNode;
  5. struct SkipListLevel {
  6. SkipListNode* forward = nullptr;
  7. int span;
  8. };
  9. struct SkipListNode {
  10. int score;
  11. int obj;
  12. SkipListLevel *level;
  13. };
  14. const int MAX_LEVEL = 20;
  15. int RandomLevel() {
  16. int level = 1;
  17. while (level < MAX_LEVEL && rand() % 2 == 0) level++;
  18. return level;
  19. }
  20. SkipListNode* CreateSkipListNode(int level, int score, int obj) {
  21. SkipListNode* node = new SkipListNode;
  22. node->score = score;
  23. node->obj = obj;
  24. node->level = new SkipListLevel[level];
  25. return node;
  26. }
  27. struct SkipList {
  28. SkipListNode* header_;
  29. int level_;
  30. int len_;
  31. SkipList() {
  32. header_ = CreateSkipListNode(MAX_LEVEL, 0, 0);
  33. level_ = len_ = 0;
  34. }
  35. void Insert(int score, int obj) {
  36. SkipListNode *update[MAX_LEVEL];
  37. int rank[MAX_LEVEL];
  38. SkipListNode* x = header_;
  39. for (int i = level_ - 1; i >= 0; i--) {
  40. rank[i] = (i == level_ - 1) ? 0 : rank[i + 1];
  41. while (x->level[i].forward && (x->level[i].forward->score < score ||
  42. x->level[i].forward->score == score &&
  43. x->level[i].forward->obj < obj)) {
  44. rank[i] += x->level[i].span;
  45. x = x->level[i].forward;
  46. }
  47. update[i] = x;
  48. }
  49. int newlevel = RandomLevel();
  50. if (newlevel > level_) {
  51. for (int i = level_; i < newlevel; i++) {
  52. update[i] = header_;
  53. update[i]->level[i].span = len_;
  54. rank[i] = 0;
  55. }
  56. }
  57. x = CreateSkipListNode(newlevel, score, obj);
  58. for (int i = 0; i < newlevel; i++) {
  59. x->level[i].forward = update[i]->level[i].forward;
  60. update[i]->level[i].forward = x;
  61. x->level[i].span = update[i]->level[i].span - (rank[0] - rank[i]);
  62. update[i]->level[i].span = rank[0] - rank[i] + 1;
  63. }
  64. for (int i = newlevel; i < level_; i++) update[i]->level[i].span++;
  65. level_ = max(level_, newlevel);
  66. len_++;
  67. }
  68. int Delete(int score, int obj) {
  69. SkipListNode *update[MAX_LEVEL];
  70. int rank[MAX_LEVEL];
  71. SkipListNode* x = header_;
  72. for (int i = level_ - 1; i >= 0; i--) {
  73. while (x->level[i].forward && (x->level[i].forward->score < score ||
  74. x->level[i].forward->score == score &&
  75. x->level[i].forward->obj < obj)) {
  76. // rank[i] += x->level[i].span;
  77. x = x->level[i].forward;
  78. }
  79. update[i] = x;
  80. }
  81. if (!(x->level[0].forward && x->level[0].forward->score == score &&
  82. x->level[0].forward->obj == obj)) return -1;
  83. x = x->level[0].forward;
  84. for (int i = 0; i < level_; i++) {
  85. if (update[i]->level[i].forward == x) {
  86. update[i]->level[i].forward = x->level[i].forward;
  87. update[i]->level[i].span += x->level[i].span - 1;
  88. } else {
  89. update[i]->level[i].span--;
  90. }
  91. }
  92. len_--;
  93. return 0;
  94. }
  95. // rank from 1
  96. int GetByRank(int rank, int& score, int& obj) const {
  97. if (rank <= 0 || rank > len_) return -1;
  98. SkipListNode* x = header_;
  99. for (int i = level_ - 1; i >= 0 && rank; i--) {
  100. while (x->level[i].forward && rank >= x->level[i].span) {
  101. rank -= x->level[i].span;
  102. x = x->level[i].forward;
  103. }
  104. }
  105. score = x->score;
  106. obj = x->obj;
  107. return 0;
  108. }
  109. int GetByScore(int score, int& obj) const {
  110. SkipListNode* x = header_;
  111. for (int i = level_ - 1; i >= 0; i--) {
  112. while (x->level[i].forward && x->level[i].forward->score < score) {
  113. x = x->level[i].forward;
  114. }
  115. }
  116. if (x->level[0].forward && x->level[0].forward->score == score) {
  117. obj = x->level[0].forward->obj;
  118. return 0;
  119. }
  120. return -1;
  121. }
  122. void Dump() const {
  123. SkipListNode* x = header_->level[0].forward;
  124. printf("size: %d\n", len_);
  125. while (x) {
  126. printf("(%d, %d)\n", x->score, x->obj);
  127. x = x->level[0].forward;
  128. }
  129. }
  130. };
  131. int main() {
  132. SkipList sl;
  133. while (1) {
  134. int type;
  135. int score, obj;
  136. scanf("%d", &type);
  137. if (type == 1) {
  138. scanf("%d%d", &score, &obj);
  139. sl.Insert(score, obj);
  140. sl.Dump();
  141. } else if (type == 2) {
  142. int rank;
  143. scanf("%d", &rank);
  144. int ret = sl.GetByRank(rank, score, obj);
  145. printf("ret=%d, rank %d: (%d, %d)\n", ret, rank, score, obj);
  146. } else if (type == 3) {
  147. scanf("%d", &score);
  148. int ret = sl.GetByScore(score, obj);
  149. printf("ret=%d, (%d, %d)\n", ret, score, obj);
  150. } else if (type == 4) {
  151. scanf("%d%d", &score, &obj);
  152. int ret = sl.Delete(score, obj);
  153. printf("ret=%d\n", ret);
  154. sl.Dump();
  155. }
  156. }
  157. return 0;
  158. }

Splay

  1. // https://loj.ac/p/104
  2. // https://loj.ac/p/105
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef pair<int, int> pii;
  7. const int N = 1e6+10;
  8. const int INF = 1e9;
  9. struct SplayNode {
  10. int weight = 0;
  11. int cnt = 0, sum = 0;
  12. int rev = 0;
  13. SplayNode* ch[2] = {};
  14. SplayNode* fa = nullptr;
  15. int Get() const { return this == fa->ch[1]; }
  16. void Maintain();
  17. void Rotate();
  18. SplayNode* Splay();
  19. SplayNode* Insert(int x);
  20. // x must exist
  21. SplayNode* Delete(int x);
  22. // x must exist
  23. int Rank(int x) const;
  24. // 1 <= k <= root->sum
  25. SplayNode* Kth(int k);
  26. int Pre(int x) const;
  27. int Suc(int x) const;
  28. SplayNode* GetMax() {
  29. return this->ch[1] ? this->ch[1]->GetMax() : this;
  30. }
  31. void PushDown();
  32. void Traverse(vector<int>&);
  33. } nodes[N];
  34. SplayNode* NewNode() {
  35. static int counter = 0;
  36. return nodes + (counter++);
  37. }
  38. void SplayNode::Maintain() {
  39. /*
  40. assert(!ch[0] || (weight > ch[0]->weight && ch[0]->cnt));
  41. assert(!ch[1] || (weight < ch[1]->weight && ch[1]->cnt));
  42. */
  43. sum = (ch[0] ? ch[0]->sum : 0) + (ch[1] ? ch[1]->sum : 0) + cnt;
  44. }
  45. void SplayNode::Rotate() {
  46. assert(this->rev == 0);
  47. // cerr << "Rorate " << this << endl;
  48. SplayNode* f = this->fa;
  49. assert(f);
  50. int flag = this->Get();
  51. if (f->fa) {
  52. f->fa->ch[f->Get()] = this;
  53. }
  54. this->fa = f->fa;
  55. f->ch[flag] = this->ch[flag ^ 1];
  56. if (this->ch[flag ^ 1]) this->ch[flag ^ 1]->fa = f;
  57. this->ch[flag ^ 1] = f;
  58. f->fa = this;
  59. f->Maintain();
  60. this->Maintain();
  61. }
  62. SplayNode* SplayNode::Splay() {
  63. // cerr << "Splay " << this << endl;
  64. while (this->fa) {
  65. this->Rotate();
  66. }
  67. return this;
  68. }
  69. SplayNode* SplayNode::Insert(int x) {
  70. // cerr << "Insert " << this << ' ' << x << endl;
  71. this->sum++;
  72. if (x == this->weight) {
  73. this->cnt++;
  74. return this;
  75. }
  76. int flag = (x > this->weight);
  77. if (this->ch[flag])
  78. return this->ch[flag]->Insert(x);
  79. SplayNode* resp = NewNode();
  80. resp->weight = x;
  81. resp->cnt = 1, resp->sum = 1;
  82. this->ch[flag] = resp;
  83. resp->fa = this;
  84. return resp;
  85. }
  86. SplayNode* SplayNode::Delete(int x) {
  87. // cerr << "Delete " << this << ' ' << x << endl;
  88. this->sum--;
  89. if (x == this->weight) {
  90. assert(this->cnt >= 1);
  91. this->cnt--;
  92. return this;
  93. }
  94. assert(this->ch[x > this->weight]);
  95. return this->ch[x > this->weight]->Delete(x);
  96. }
  97. int SplayNode::Rank(int x) const {
  98. if (this->weight == x) return this->ch[0] ? this->ch[0]->sum : 0;
  99. if (this->weight > x) return this->ch[0] ? this->ch[0]->Rank(x) : 0;
  100. return (this->ch[0] ? this->ch[0]->sum : 0) + this->cnt + (this->ch[1] ? this->ch[1]->Rank(x) : 0);
  101. }
  102. SplayNode* SplayNode::Kth(int k) {
  103. this->PushDown();
  104. if (this->ch[0] && this->ch[0]->sum >= k)
  105. return this->ch[0]->Kth(k);
  106. k -= (this->ch[0] ? this->ch[0]->sum : 0);
  107. if (this->cnt >= k) return this;
  108. return this->ch[1]->Kth(k - this->cnt);
  109. }
  110. int SplayNode::Pre(int x) const {
  111. if (x <= this->weight) return this->ch[0] ? this->ch[0]->Pre(x) : -INF;
  112. return max(this->weight, this->ch[1] ? this->ch[1]->Pre(x) : -INF);
  113. }
  114. int SplayNode::Suc(int x) const {
  115. if (x >= this->weight) return this->ch[1] ? this->ch[1]->Suc(x) : INF;
  116. return min(this->weight, this->ch[0] ? this->ch[0]->Suc(x) : INF);
  117. }
  118. void SplayNode::PushDown() {
  119. if (this->rev) {
  120. if (this->ch[0]) this->ch[0]->rev ^= 1;
  121. if (this->ch[1]) this->ch[1]->rev ^= 1;
  122. swap(this->ch[0], this->ch[1]);
  123. this->rev = 0;
  124. }
  125. }
  126. void SplayNode::Traverse(vector<int>& res) {
  127. this->PushDown();
  128. if (this->ch[0]) this->ch[0]->Traverse(res);
  129. res.push_back(this->weight);
  130. if (this->ch[1]) this->ch[1]->Traverse(res);
  131. }
  132. struct SplayTree {
  133. SplayNode* root = nullptr;
  134. void Insert(int x) {
  135. if (root == nullptr) {
  136. root = NewNode();
  137. root->weight = x;
  138. root->cnt = root->sum = 1;
  139. } else {
  140. root = root->Insert(x)->Splay();
  141. }
  142. }
  143. void Delete(int x) {
  144. root = root->Delete(x)->Splay();
  145. if (root->cnt == 0) {
  146. if (root->ch[0] == nullptr) {
  147. root = root->ch[1];
  148. root->fa = nullptr;
  149. } else if (root->ch[1] == nullptr) {
  150. root = root->ch[0];
  151. root->fa = nullptr;
  152. } else {
  153. root->ch[0]->fa = nullptr;
  154. SplayNode* s = root->ch[0]->GetMax();
  155. s->Splay();
  156. assert(s->ch[1] == nullptr);
  157. s->ch[1] = root->ch[1];
  158. root->ch[1]->fa = s;
  159. s->Maintain();
  160. root = s;
  161. }
  162. }
  163. }
  164. int Rank(int x) { return root->Rank(x); }
  165. SplayNode* Kth(int x) { return root->Kth(x); }
  166. int Pre(int x) { return root->Pre(x); }
  167. int Suc(int x) { return root->Suc(x); }
  168. void Traverse(vector<int>& res) { root->Traverse(res); }
  169. };
  170. void solve() {
  171. int n, m;
  172. scanf("%d%d", &n, &m);
  173. SplayTree tr;
  174. for (int i = 0; i <= n+1; i++) tr.Insert(i);
  175. while (m--) {
  176. int l, r;
  177. scanf("%d%d", &l, &r);
  178. tr.root = tr.Kth(l-1 + 1)->Splay();
  179. tr.root = tr.Kth(r+1 + 1)->Splay();
  180. assert(tr.root->ch[0]);
  181. assert(tr.root->ch[0]->ch[1]);
  182. tr.root->ch[0]->ch[1]->rev ^= 1;
  183. }
  184. vector<int> ans;
  185. tr.Traverse(ans);
  186. assert(ans.size() == n+2);
  187. for (int i = 1; i <= n; i++) {
  188. if (i > 1) printf(" ");
  189. printf("%d", ans[i]);
  190. }
  191. printf("\n");
  192. }
  193. int main() {
  194. int T = 1;
  195. // scanf("%d", &T);
  196. while (T--) solve();
  197. return 0;
  198. }

Treap

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. struct TreapNode {
  4. static const int SIZE = 1e5 + 10;
  5. static int counter;
  6. TreapNode *son[2], *fa;
  7. int val, rank, size, id;
  8. void Reset() {
  9. son[0] = son[1] = fa = nullptr;
  10. rank = rand();
  11. }
  12. TreapNode() { Reset(); }
  13. void PushUp() {
  14. size = 1;
  15. if (son[0]) size += son[0]->size;
  16. if (son[1]) size += son[1]->size;
  17. }
  18. void print() const {
  19. printf("id: %d, val: %d\n", id, val);
  20. }
  21. } nodes[TreapNode::SIZE];
  22. int TreapNode::counter = 0;
  23. TreapNode* CreateTreapNode(int val, int id) {
  24. TreapNode* node = &nodes[TreapNode::counter++];
  25. node->val = val;
  26. node->id = id;
  27. node->size = 1;
  28. return node;
  29. }
  30. struct Treap {
  31. TreapNode* head;
  32. void Reset() {
  33. for (int i = 0; i < TreapNode::counter; i++) nodes[i].Reset();
  34. TreapNode::counter = 0;
  35. head = CreateTreapNode(INT_MIN, 0);
  36. head->rank = -1;
  37. }
  38. Treap() { Reset(); }
  39. static int SonType(TreapNode* x) {
  40. return x->fa->son[1] == x;
  41. }
  42. static void GenChildren(TreapNode* fa, TreapNode* son, int type) {
  43. fa->son[type] = son;
  44. if (son) son->fa = fa;
  45. }
  46. // if exist already, ingore
  47. void Insert(int val, int id) {
  48. TreapNode* x = CreateTreapNode(val, id);
  49. TreapNode* cur = head;
  50. while (1) {
  51. // if (cur->val == val) return;
  52. cur->size++;
  53. int flag = cur->val < val;
  54. if (cur->son[flag] == nullptr) { cur->son[flag] = x, x->fa = cur; break; }
  55. else cur = cur->son[flag];
  56. }
  57. assert(x->fa);
  58. while (x->rank < x->fa->rank) {
  59. int flag = SonType(x);
  60. TreapNode* fa = x->fa;
  61. assert(fa->fa);
  62. GenChildren(fa->fa, x, SonType(fa));
  63. GenChildren(fa, x->son[flag^1], flag);
  64. GenChildren(x, fa, flag^1);
  65. fa->PushUp();
  66. x->PushUp();
  67. }
  68. }
  69. // todo
  70. void Delete(int val) {
  71. }
  72. const TreapNode* SeekUpperBound(int val) {
  73. TreapNode* cur = head;
  74. TreapNode* ans = nullptr;
  75. while (cur) {
  76. if (cur->val > val) ans = cur, cur = cur->son[0];
  77. else cur = cur->son[1];
  78. }
  79. // assert(ans);
  80. return ans;
  81. }
  82. const TreapNode* SeekLowerBound(int val) {
  83. TreapNode* cur = head;
  84. TreapNode* ans = nullptr;
  85. while (cur) {
  86. if (cur->val < val) ans = cur, cur = cur->son[1];
  87. else cur = cur->son[0];
  88. }
  89. // assert(ans);
  90. return ans;
  91. }
  92. // from 1
  93. const TreapNode* GetByRank(int rank) {
  94. rank++;
  95. TreapNode* cur = head;
  96. if (rank > cur->size) return nullptr;
  97. while (cur) {
  98. if (cur->son[0]) {
  99. if (cur->son[0]->size >= rank) { cur = cur->son[0]; continue; }
  100. rank -= cur->son[0]->size;
  101. }
  102. if (rank == 1) return cur;
  103. rank--;
  104. cur = cur->son[1];
  105. }
  106. return nullptr;
  107. }
  108. } treap;
  109. void SolveHDU4585() {
  110. int n;
  111. while (~scanf("%d", &n) && n) {
  112. treap.Reset();
  113. treap.Insert(1000000000, 1);
  114. treap.Insert(-1000000000, 1);
  115. int id, val;
  116. while (n--) {
  117. scanf("%d%d", &id, &val);
  118. treap.Insert(val, id);
  119. const TreapNode* lower = treap.SeekLowerBound(val);
  120. const TreapNode* upper = treap.SeekUpperBound(val);
  121. if (val - lower->val <= upper->val - val) {
  122. printf("%d %d\n", id, lower->id);
  123. } else {
  124. printf("%d %d\n", id, upper->id);
  125. }
  126. }
  127. }
  128. }
  129. void SolveUVA10107() {
  130. int n, counter = 0;
  131. while (~scanf("%d", &n)) {
  132. counter++;
  133. treap.Insert(n, 0);
  134. if (counter & 1) {
  135. printf("%d\n", treap.GetByRank(counter/2 + 1)->val);
  136. } else {
  137. printf("%lld\n", (0LL + treap.GetByRank(counter/2)->val + treap.GetByRank(counter/2+1)->val)/2);
  138. }
  139. }
  140. }
  141. int main() {
  142. SolveUVA10107();
  143. // SolveHDU4585();
  144. return 0;
  145. }

Graph Theory

2-SAT

  1. // https://atcoder.jp/contests/abc210/tasks/abc210_f
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. struct SCC {
  7. static const int N = 30000 * 22 * 2 * 2 + 100;
  8. vector<int> G[N];
  9. vector<int> rG[N];
  10. bool vis[N];
  11. int id[N];
  12. vector<int> cmp[N];
  13. SCC() {
  14. memset(vis, 0, sizeof(vis));
  15. }
  16. // a --> b
  17. // !a || b
  18. // a -> b and !b -> !a
  19. void Infer(int u, int v) {
  20. AddEdge(u, v);
  21. AddEdge(v^1, u^1);
  22. }
  23. void AddEdge(int u, int v) {
  24. G[u].push_back(v);
  25. rG[v].push_back(u);
  26. }
  27. void dfs(int u, vector<int>& orders) {
  28. vis[u] = 1;
  29. for (const int v : G[u]) {
  30. if (!vis[v]) dfs(v, orders);
  31. }
  32. orders.push_back(u);
  33. }
  34. void rdfs(int u, int k) {
  35. vis[u] = 1;
  36. id[u] = k, cmp[k].push_back(u);
  37. for (const int v : rG[u]) {
  38. if (!vis[v]) rdfs(v, k);
  39. }
  40. }
  41. void run(int n) {
  42. vector<int> orders;
  43. for (int i = 0; i < n; i++) {
  44. if (!vis[i]) dfs(i, orders);
  45. }
  46. reverse(orders.begin(), orders.end());
  47. std::fill(vis, vis+n, false);
  48. int k = 0;
  49. for (const int u : orders) {
  50. if (!vis[u]) {
  51. rdfs(u, ++k);
  52. }
  53. }
  54. }
  55. } scc;
  56. const int M = 2e6 + 10;
  57. int mip[M];
  58. vector<int> primes;
  59. void init() {
  60. mip[1] = 1;
  61. for (int i = 2; i < M; i++) {
  62. if (mip[i] == 0) mip[i] = i, primes.push_back(i);
  63. for (const int p : primes) {
  64. int u = p * i;
  65. if (u >= M) break;
  66. mip[u] = p;
  67. if (i % p == 0) break;
  68. }
  69. }
  70. }
  71. vector<int> GetPrimeFactors(int n) {
  72. vector<int> res;
  73. while (n > 1) {
  74. int p = mip[n];
  75. res.push_back(p);
  76. while (n % p == 0) n /= p;
  77. }
  78. return res;
  79. }
  80. vector<pii> X[M];
  81. void solve() {
  82. init();
  83. int n;
  84. scanf("%d", &n);
  85. int cur = n;
  86. for (int i = 0; i < n; i++) {
  87. int a, b;
  88. scanf("%d%d", &a, &b);
  89. for (const int p : GetPrimeFactors(a)) {
  90. X[p].push_back(pii(i << 1, cur++ << 1));
  91. }
  92. for (const int p : GetPrimeFactors(b)) {
  93. X[p].push_back(pii(i << 1 | 1, cur++ << 1));
  94. }
  95. }
  96. for (int i = 2; i < M; i++) {
  97. const auto& xp = X[i];
  98. int sz = xp.size();
  99. if (sz <= 1) continue;
  100. for (int i = 0; i < sz; i++) {
  101. if (i+1 < sz) {
  102. scc.Infer(xp[i].first, xp[i+1].second);
  103. scc.Infer(xp[i].second, xp[i+1].second);
  104. }
  105. scc.Infer(xp[i].second, xp[i].first ^ 1);
  106. }
  107. }
  108. scc.run(2*cur);
  109. // topo order of x > topo order of !x <==> x is ture
  110. for (int i = 0; i < cur; i++) {
  111. if (scc.id[i << 1] == scc.id[i << 1 | 1]) {
  112. printf("No\n");
  113. return ;
  114. }
  115. }
  116. printf("Yes\n");
  117. }
  118. int main() {
  119. int T = 1;
  120. // scanf("%d", &T);
  121. while (T--) solve();
  122. return 0;
  123. }

Cut Point

  1. // author: yang12138
  2. // https://www.luogu.com.cn/problem/P3388
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef pair<int, int> pii;
  7. const int N = 1e5+10;
  8. const int M = 1e5+10;
  9. vector<pii> G[N];
  10. int low[N], ord[N], cnt = 0;
  11. bool vise[M];
  12. void DFS(int u, int f, vector<int>& ans) {
  13. ord[u] = low[u] = ++cnt;
  14. bool flag = 0;
  15. int son = 0;
  16. for (auto [v, eid] : G[u]) {
  17. if (vise[eid]) continue;
  18. vise[eid] = 1;
  19. if (!low[v]) {
  20. DFS(v, u, ans);
  21. low[u] = min(low[u], low[v]);
  22. if (low[v] >= ord[u]) flag = 1;
  23. son++;
  24. } else {
  25. low[u] = min(low[u], ord[v]);
  26. }
  27. }
  28. if (f ? flag : (son > 1)) {
  29. ans.push_back(u);
  30. }
  31. }
  32. void solve() {
  33. int n, m;
  34. scanf("%d%d", &n, &m);
  35. for (int i = 0; i < m; i++) {
  36. int u, v;
  37. scanf("%d%d", &u, &v);
  38. G[u].push_back(pii(v, i));
  39. G[v].push_back(pii(u, i));
  40. }
  41. vector<int> ans;
  42. for (int i = 1; i <= n; i++)
  43. if (!low[i])
  44. DFS(i, 0, ans);
  45. sort(ans.begin(), ans.end());
  46. printf("%d\n", (int)ans.size());
  47. for (int i : ans) printf("%d ", i);
  48. printf("\n");
  49. }
  50. int main() {
  51. int T = 1;
  52. // scanf("%d", &T);
  53. while (T--) solve();
  54. return 0;
  55. }

Edge BCC

  1. // author: yang12138
  2. // https://www.luogu.com.cn/problem/P2860
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef pair<int, int> pii;
  7. const int N = 1e5+10;
  8. const int M = 1e5+10;
  9. vector<pii> G[N];
  10. vector<int> G2[N];
  11. vector<pii> edges;
  12. int low[N], ord[N], cnt = 0;
  13. bool vise[M];
  14. int id[N], deg[N];
  15. void DFS(int u, int f) {
  16. ord[u] = low[u] = ++cnt;
  17. for (auto [v, eid] : G[u]) {
  18. if (vise[eid]) continue;
  19. vise[eid] = 1;
  20. if (!low[v])
  21. DFS(v, u), low[u] = min(low[u], low[v]);
  22. else
  23. low[u] = min(low[u], ord[v]);
  24. }
  25. if (low[u] < ord[u]) {
  26. G2[u].push_back(f);
  27. G2[f].push_back(u);
  28. }
  29. }
  30. void DFS2(int u, int k) {
  31. id[u] = k;
  32. for (auto v : G2[u])
  33. if (!id[v]) DFS2(v, k);
  34. }
  35. void solve() {
  36. int n, m;
  37. scanf("%d%d", &n, &m);
  38. for (int i = 0; i < m; i++) {
  39. int u, v;
  40. scanf("%d%d", &u, &v);
  41. G[u].push_back(pii(v, i));
  42. G[v].push_back(pii(u, i));
  43. edges.push_back(pii(u, v));
  44. }
  45. DFS(1, 0);
  46. int k = 0;
  47. for (int i = 1; i <= n; i++)
  48. if (!id[i]) DFS2(i, ++k);
  49. int ecnt = 0;
  50. for (auto [u, v] : edges) {
  51. if (id[u] != id[v])
  52. deg[id[u]]++, deg[id[v]]++, ecnt++;
  53. }
  54. assert(ecnt == k - 1);
  55. int ans = 0;
  56. for (int i = 1; i <= k; i++) {
  57. ans += (deg[i] == 1);
  58. }
  59. printf("%d\n", k == 1 ? 0 : (ans + 1) / 2);
  60. }
  61. int main() {
  62. int T = 1;
  63. // scanf("%d", &T);
  64. while (T--) solve();
  65. return 0;
  66. }

Tree

Divide And Conquer 1

  1. // http://poj.org/problem?id=1741
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const int N = 1e4 + 10;
  7. const int INF = 1e9;
  8. vector<pii> G[N];
  9. bool is_centroid[N];
  10. int D;
  11. int GetSubTreeSize(int u, int f) {
  12. int ans = 1;
  13. for (const auto pir : G[u]) {
  14. int v = pir.first;
  15. if (is_centroid[v] || v == f) continue;
  16. ans += GetSubTreeSize(v, u);
  17. }
  18. return ans;
  19. }
  20. int SearchCentroid(int u, int f, const int size, pii& res) {
  21. int maxsize = 0, sum = 0;
  22. for (const auto pir : G[u]) {
  23. int v = pir.first;
  24. if (is_centroid[v] || v == f) continue;
  25. int tmp = SearchCentroid(v, u, size, res);
  26. maxsize = max(maxsize, tmp);
  27. sum += tmp;
  28. }
  29. maxsize = max(maxsize, size - 1 - sum);
  30. if (maxsize < res.first) res = pii(maxsize, u);
  31. return sum + 1;
  32. }
  33. void GetPaths(int u, int f, int d, vector<int>& paths) {
  34. paths.push_back(d);
  35. for (const auto pir : G[u]) {
  36. int v = pir.first;
  37. if (is_centroid[v] || v == f) continue;
  38. GetPaths(v, u, d + pir.second, paths);
  39. }
  40. }
  41. int Calc(vector<int>& ds) {
  42. sort(ds.begin(), ds.end());
  43. int l = 0, r = ds.size() - 1;
  44. int ans = 0;
  45. while (l < r) {
  46. while (r > l && ds[l] + ds[r] > D) r--;
  47. if (r <= l) break;
  48. ans += r - l;
  49. l++;
  50. }
  51. return ans;
  52. }
  53. void DivideAndConquer(int u, int& ans) {
  54. int size = GetSubTreeSize(u, 0);
  55. pii res(INF, 0);
  56. SearchCentroid(u, 0, size, res);
  57. const int root = res.second;
  58. assert(root);
  59. is_centroid[root] = 1;
  60. vector<int> paths = {0};
  61. for (const auto pir : G[root]) {
  62. int v = pir.first;
  63. if (!is_centroid[v]) {
  64. DivideAndConquer(v, ans);
  65. vector<int> tmp;
  66. GetPaths(v, 0, pir.second, tmp);
  67. paths.insert(paths.end(), tmp.begin(), tmp.end());
  68. ans -= Calc(tmp);
  69. }
  70. }
  71. ans += Calc(paths);
  72. is_centroid[root] = 0;
  73. }
  74. bool solve() {
  75. int n;
  76. scanf("%d%d", &n, &D);
  77. if (n == 0 && D == 0) return false;
  78. for (int i = 1; i <= n; i++) G[i].clear();
  79. for (int i = 1; i < n; i++) {
  80. int u, v, w;
  81. scanf("%d%d%d", &u, &v, &w);
  82. G[u].push_back(pii(v, w));
  83. G[v].push_back(pii(u, w));
  84. }
  85. int ans = 0;
  86. DivideAndConquer(1, ans);
  87. printf("%d\n", ans);
  88. return true;
  89. }
  90. int main() {
  91. while (solve());
  92. return 0;
  93. }

Divide And Conquer 2

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef pair<int, int> pii;
  4. typedef bitset<100010> BitSet;
  5. const int N = 3005;
  6. vector<int> G[N];
  7. int sz[N], is_centroid[N], w[N];
  8. int FindTreeSize(int u, int f) {
  9. int ret = 1;
  10. for (int v : G[u]) {
  11. if (v == f || is_centroid[v]) continue;
  12. ret += FindTreeSize(v, u);
  13. }
  14. return ret;
  15. }
  16. pii FindRoot(int u, int f, int ssz) {
  17. sz[u] = 1;
  18. pii ret(N, 0);
  19. int ma = 0;
  20. for (int v : G[u]) {
  21. if (v == f || is_centroid[v]) continue;
  22. ret = min(ret, FindRoot(v, u, ssz));
  23. sz[u] += sz[v];
  24. ma = max(ma, sz[v]);
  25. }
  26. ma = max(ma, ssz - sz[u]);
  27. return min(ret, pii(ma, u));
  28. }
  29. void DP(int u, int f, BitSet& pre) {
  30. BitSet cur = (pre << w[u]);
  31. for (int v : G[u]) {
  32. if (v == f || is_centroid[v]) continue;
  33. DP(v, u, cur);
  34. }
  35. pre |= cur;
  36. }
  37. void DFS(int u, BitSet& ret) {
  38. int root = FindRoot(u, 0, FindTreeSize(u, 0)).second;
  39. assert(root);
  40. BitSet bs;
  41. bs[0] = 1;
  42. DP(root, 0, bs);
  43. ret |= bs;
  44. is_centroid[root] = 1;
  45. for (int v : G[root]) {
  46. if (!is_centroid[v]) {
  47. DFS(v, ret);
  48. }
  49. }
  50. is_centroid[root] = 0;
  51. }
  52. void solve() {
  53. int n, m;
  54. scanf("%d%d", &n, &m);
  55. for (int i = 1; i <= n; i++) {
  56. G[i].clear();
  57. sz[i] = is_centroid[i] = 0;
  58. }
  59. for (int i = 1; i < n; i++) {
  60. int u, v;
  61. scanf("%d%d", &u, &v);
  62. G[u].push_back(v);
  63. G[v].push_back(u);
  64. }
  65. for (int i = 1; i <= n; i++) {
  66. scanf("%d", w + i);
  67. }
  68. BitSet ret;
  69. DFS(1, ret);
  70. for (int i = 1; i <= m; i++) printf("%d", int(ret[i]));
  71. printf("\n");
  72. }
  73. int main() {
  74. int T;
  75. scanf("%d", &T);
  76. while (T--) solve();
  77. return 0;
  78. }

Steiner Tree

  1. // https://www.luogu.com.cn/problem/P6192
  2. // n points, m edges, k key points
  3. // O(n3^k) + O(2^kmlogn)
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. typedef long long ll;
  7. typedef pair<int, int> pii;
  8. const int N = 105;
  9. const int K = 10;
  10. const int INF = 1e9;
  11. int key_point[K];
  12. vector<pii> G[N];
  13. priority_queue<pii, vector<pii>, greater<pii>> que;
  14. void Dijkstra(int* dis) {
  15. while (!que.empty()) {
  16. pii t = que.top(); que.pop();
  17. int u = t.second;
  18. if (dis[u] < t.first) continue;
  19. for (auto e : G[u]) {
  20. int v = e.first, w = e.second;
  21. if (dis[v] > dis[u] + w) {
  22. dis[v] = dis[u] + w;
  23. que.push(pii(dis[v], v));
  24. }
  25. }
  26. }
  27. }
  28. int dis[1 << K][N];
  29. void solve() {
  30. int n, m, k;
  31. scanf("%d%d%d", &n, &m, &k);
  32. for (int i = 1; i <= m; i++) {
  33. int u, v, w;
  34. scanf("%d%d%d", &u, &v, &w);
  35. G[u].push_back(pii(v, w));
  36. G[v].push_back(pii(u, w));
  37. }
  38. for (int s = 1; s < (1 << k); s++) fill(dis[s] + 1, dis[s] + n + 1, INF);
  39. for (int i = 0; i < k; i++) {
  40. scanf("%d", key_point + i);
  41. dis[1 << i][key_point[i]] = 0;
  42. }
  43. for (int s = 1; s < (1 << k); s++) {
  44. for (int i = 1; i <= n; i++) {
  45. for (int mask = (s & (s - 1)); mask; mask = ((mask - 1) & s)) {
  46. dis[s][i] = min(dis[s][i], dis[mask][i] + dis[mask ^ s][i]);
  47. }
  48. if (dis[s][i] < INF)
  49. que.push(pii(dis[s][i], i));
  50. }
  51. Dijkstra(dis[s]);
  52. }
  53. printf("%d\n", dis[(1 << k) - 1][key_point[0]]);
  54. }
  55. int main() {
  56. int T = 1;
  57. // scanf("%d", &T);
  58. while (T--) solve();
  59. return 0;
  60. }

Tree-Chain Split

  1. // https://www.spoj.com/problems/QTREE/en/
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. #define lson (root << 1)
  7. #define rson (root << 1 | 1)
  8. const int N = 1e4 + 10;
  9. struct Edge {
  10. int u, v, w;
  11. void scan() { scanf("%d%d%d", &u, &v, &w); }
  12. } E[N];
  13. struct SegTree {
  14. int val[N << 2];
  15. SegTree() {
  16. Clear();
  17. }
  18. void Clear() {
  19. memset(val, 0, sizeof(val));
  20. }
  21. void Update(int root, int l, int r, int pos, int v) {
  22. if (l == r) {
  23. val[root] = v;
  24. return ;
  25. }
  26. int m = (l + r) / 2;
  27. if (pos <= m) Update(lson, l, m, pos, v);
  28. else Update(rson, m+1, r, pos, v);
  29. val[root] = max(val[lson], val[rson]);
  30. }
  31. int Query(int root, int l, int r, int a, int b) {
  32. if (l == a && r == b) return val[root];
  33. int m = (l + r) / 2;
  34. if (b <= m) return Query(lson, l, m, a, b);
  35. else if (a > m) return Query(rson, m+1, r, a, b);
  36. return max(Query(lson, l, m, a, m), Query(rson, m+1, r, m+1, b));
  37. }
  38. } bt;
  39. vector<pii> G[N];
  40. int fa[N], sz[N], son[N], dep[N];
  41. int top[N], rk[N], cnt = 0;
  42. void dfs1(int u, int f, int d) {
  43. fa[u] = f, dep[u] = d;
  44. son[u] = -1, sz[u] = 1;
  45. for (const auto pir : G[u]) {
  46. int v = pir.first;
  47. if (v == f) continue;
  48. dfs1(v, u, d + 1);
  49. if (son[u] == -1 || sz[v] > sz[son[u]]) son[u] = v;
  50. }
  51. }
  52. int n;
  53. void dfs2(int u, int t) {
  54. top[u] = t, rk[u] = ++cnt;
  55. if (son[u] != -1) dfs2(son[u], t);
  56. for (const auto pir : G[u]) {
  57. int v = pir.first;
  58. if (v == fa[u] || v == son[u]) continue;
  59. dfs2(v, v);
  60. }
  61. for (const auto pir : G[u]) {
  62. int v = pir.first;
  63. if (v == fa[u]) continue;
  64. bt.Update(1, 1, n, rk[v], pir.second);
  65. }
  66. }
  67. int Query(int u, int v) {
  68. // if (u == v) return 0;
  69. int ans = 0;
  70. while (top[u] != top[v]) {
  71. if (dep[top[u]] < dep[top[v]]) swap(u, v);
  72. ans = max(ans, bt.Query(1, 1, n, rk[top[u]], rk[u]));
  73. u = fa[top[u]];
  74. }
  75. if (u != v) {
  76. if (dep[u] > dep[v]) swap(u, v);
  77. ans = max(ans, bt.Query(1, 1, n, rk[u]+1, rk[v]));
  78. }
  79. return ans;
  80. }
  81. void solve() {
  82. scanf("%d", &n);
  83. for (int i = 1; i <= n; i++) G[i].clear();
  84. cnt = 0, bt.Clear();
  85. for (int i = 1; i < n; i++) {
  86. E[i].scan();
  87. G[E[i].u].push_back(pii(E[i].v, E[i].w));
  88. G[E[i].v].push_back(pii(E[i].u, E[i].w));
  89. }
  90. dfs1(1, 0, 0);
  91. dfs2(1, 1);
  92. char s[10];
  93. int a, b;
  94. while (1) {
  95. scanf("%s", s);
  96. if (s[0] == 'D') break;
  97. scanf("%d%d", &a, &b);
  98. if (s[0] == 'C') {
  99. int u = E[a].u, v = E[a].v;
  100. if (u != fa[v]) swap(u, v);
  101. assert(u == fa[v]);
  102. bt.Update(1, 1, n, rk[v], b);
  103. } else {
  104. printf("%d\n", Query(a, b));
  105. }
  106. }
  107. }
  108. int main() {
  109. int T = 1;
  110. scanf("%d", &T);
  111. while (T--) solve();
  112. return 0;
  113. }

Virtual Tree

  1. // author: yang12138
  2. // https://oi-wiki.org/graph/virtual-tree/
  3. // https://www.luogu.com.cn/record/75047671
  4. #include <bits/stdc++.h>
  5. using namespace std;
  6. typedef long long ll;
  7. typedef pair<int, int> pii;
  8. const int N = 3e5+10;
  9. const int INF = 1e9;
  10. int fa[N][20];
  11. int wi[N][20];
  12. int dep[N];
  13. vector<pii> G[N];
  14. int id[N], cnt = 0;
  15. int GetLCA(int u, int v) {
  16. if (dep[u] < dep[v]) swap(u, v);
  17. int d = dep[u] - dep[v];
  18. for (int i = 19; i >= 0; i--) {
  19. if ((d >> i) & 1)
  20. u = fa[u][i];
  21. }
  22. if (u == v) return u;
  23. for (int i = 19; i >= 0; i--) {
  24. if (fa[u][i] != fa[v][i])
  25. u = fa[u][i], v = fa[v][i];
  26. }
  27. return fa[u][0];
  28. }
  29. int GetMinWi(int f, int u) {
  30. int d = dep[u] - dep[f];
  31. int ans = INF;
  32. for (int i = 19; i >= 0; i--) {
  33. if ((d >> i) & 1) {
  34. ans = min(ans, wi[u][i]);
  35. u = fa[u][i];
  36. }
  37. }
  38. assert(u == f);
  39. return ans;
  40. }
  41. void DFS(int u, int f, int d, int w) {
  42. fa[u][0] = f, dep[u] = d, wi[u][0] = w, id[u] = ++cnt;
  43. for (int i = 1; i < 20; i++) {
  44. fa[u][i] = fa[fa[u][i-1]][i-1];
  45. wi[u][i] = min(wi[u][i-1], wi[fa[u][i-1]][i-1]);
  46. }
  47. for (auto [v, w1] : G[u]) {
  48. if (v != f) DFS(v, u, d + 1, w1);
  49. }
  50. }
  51. vector<pii> G2[N];
  52. void AddEdge(int u, int v) {
  53. G2[u].push_back(pii(v, GetMinWi(u, v)));
  54. }
  55. bool is[N];
  56. ll DP(int u, vector<int>& vs) {
  57. vs.push_back(u);
  58. ll dp = 0;
  59. for (auto [v, w] : G2[u]) {
  60. ll tdp = DP(v, vs);
  61. dp += is[v] ? w : min(1LL*w, tdp);
  62. }
  63. return dp;
  64. }
  65. int sta[N];
  66. ll Solve(vector<int>& h) {
  67. sort(h.begin(), h.end(), [](int a, int b) { return id[a] < id[b]; });
  68. int top = 0;
  69. sta[top++] = 1;
  70. for (const int i : h) {
  71. is[i] = 1;
  72. assert(i != 1);
  73. int lca = GetLCA(sta[top - 1], i);
  74. if (lca != sta[top - 1]) {
  75. while (id[lca] < id[sta[top - 2]]) {
  76. AddEdge(sta[top - 2], sta[top - 1]);
  77. top--;
  78. }
  79. AddEdge(lca, sta[top - 1]);
  80. if (id[lca] != id[sta[top - 2]]) {
  81. sta[top - 1] = lca;
  82. } else {
  83. top--;
  84. }
  85. }
  86. sta[top++] = i;
  87. }
  88. for (int i = 0; i + 1 < top; i++)
  89. AddEdge(sta[i], sta[i + 1]);
  90. vector<int> vs;
  91. ll ans = DP(1, vs);
  92. for (int i : vs) G2[i].clear();
  93. for (int i : h) is[i] = 0;
  94. return ans;
  95. }
  96. void solve() {
  97. int n;
  98. scanf("%d", &n);
  99. for (int i = 1; i < n; i++) {
  100. int u, v, w;
  101. scanf("%d%d%d", &u, &v, &w);
  102. G[u].push_back(pii(v, w));
  103. G[v].push_back(pii(u, w));
  104. }
  105. DFS(1, 0, 0, 0);
  106. int m;
  107. scanf("%d", &m);
  108. while (m--) {
  109. int k;
  110. scanf("%d", &k);
  111. vector<int> h(k);
  112. for (int i = 0; i < k; i++) scanf("%d", &h[i]);
  113. printf("%lld\n", Solve(h));
  114. }
  115. }
  116. int main() {
  117. int T = 1;
  118. // scanf("%d", &T);
  119. while (T--) solve();
  120. return 0;
  121. }

Math

Fast Walsh Transform

  1. // author: yang12138
  2. // ref: https://oi-wiki.org/math/poly/fwt/
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. // C = A \oplus B
  7. // FWT(C) = FWT(A) * FWT(B)
  8. // sig(i & j) ^ sig(i & k) = sig(i & (j ^ k))
  9. // xor: A'(i) = \sum_{j}((-1)^sig(i & j) * A_j)
  10. // or: A'(i) = \sum_{i=j|i}A_j
  11. // and: A'(i) = \sum_{i=j&i}A_j
  12. void FWT(vector<ll>& a, int flag) {
  13. int n = a.size();
  14. assert((n & (n - 1)) == 0);
  15. for (int w = 2; w <= n; w <<= 1) {
  16. for (int i = 0; i < n; i += w) {
  17. for (int j = i; j < i + w / 2; j++) {
  18. ll u = a[j], v = a[j + w / 2];
  19. if (flag == 1) {
  20. // xor
  21. a[j] = u + v, a[j + w / 2] = u - v;
  22. // or
  23. // a[j] = u, a[j + w / 2] = u + v;
  24. // and
  25. // a[j] = u + v, a[j + w / 2] = v;
  26. } else {
  27. // xor
  28. a[j] = (u + v) / 2, a[j + w / 2] = (u - v) / 2;
  29. // or
  30. // a[j] = u, a[j + w / 2] = v - u;
  31. // and
  32. // a[j] = u - v, a[j + w / 2] = v;
  33. }
  34. }
  35. }
  36. }
  37. }
  38. void solve() {
  39. srand(time(nullptr));
  40. int n;
  41. cin >> n;
  42. vector<ll> a(n), b(n);
  43. for (int i = 0; i < n; i++) a[i] = rand() % 100000;
  44. for (int i = 0; i < n; i++) b[i] = rand() % 100000;
  45. auto Print = [](const vector<ll>& a) {
  46. for (ll i : a) printf("%lld ", i);
  47. printf("\n");
  48. };
  49. vector<ll> c(n);
  50. for (int i = 0; i < n; i++) {
  51. for (int j = 0; j < n; j++) {
  52. c[i ^ j] += a[i] * b[j];
  53. }
  54. }
  55. printf("baoli result\n");
  56. Print(c);
  57. FWT(a, 1);
  58. FWT(b, 1);
  59. vector<ll> d(n);
  60. for (int i = 0; i < n; i++) d[i] = a[i] * b[i];
  61. FWT(d, -1);
  62. printf("FWT result\n");
  63. Print(d);
  64. bool succ = true;
  65. for (int i = 0; i < n; i++)
  66. succ &= (c[i] == d[i]);
  67. printf("test %s\n", succ ? "succ" : "fail");
  68. }
  69. int main() {
  70. int T = 1;
  71. // scanf("%d", &T);
  72. while (T--) solve();
  73. return 0;
  74. }

Fast Fourier Transform

  1. // https://acm.hdu.edu.cn/showproblem.php?pid=1402
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef std::complex<double> Complex;
  6. const double pi = acos(-1.0);
  7. void DFT(vector<Complex>& a, const int opt) {
  8. int n = a.size();
  9. if (n <= 1) return ;
  10. assert(!(n & (n - 1)));
  11. for (int i = 0, j = 0; i < n - 1; i++) {
  12. if (i < j) swap(a[i], a[j]);
  13. int k = n >> 1;
  14. while (j >= k) j -= k, k >>= 1;
  15. j += k;
  16. }
  17. for (int i = 2; i <= n; i <<= 1) {
  18. Complex wn = exp(Complex(0, opt * 2.0 * pi / i));
  19. for (int j = 0; j < n; j += i) {
  20. Complex w(1, 0);
  21. for (int k = 0; k < i / 2; k++) {
  22. Complex u = a[j + k];
  23. Complex v = w * a[j + k + i / 2];
  24. a[j + k] = u + v;
  25. a[j + k + i / 2] = u - v;
  26. w = w * wn;
  27. }
  28. }
  29. }
  30. if (opt == -1) {
  31. for (int i = 0; i < n; i++) a[i] /= n;
  32. }
  33. }
  34. vector<int> FFT(const vector<int>& a, const vector<int>& b) {
  35. int len = 1;
  36. while (len < max(a.size(), b.size())) len <<= 1;
  37. len <<= 1;
  38. vector<Complex> ca(len), cb(len);
  39. for (int i = 0; i < a.size(); i++) ca[i] = Complex(a[i], 0);
  40. for (int i = 0; i < b.size(); i++) cb[i] = Complex(b[i], 0);
  41. DFT(ca, 1);
  42. DFT(cb, 1);
  43. vector<Complex> cc(len);
  44. for (int i = 0; i < len; i++) cc[i] = ca[i] * cb[i];
  45. DFT(cc, -1);
  46. vector<int> c(len);
  47. for (int i = 0; i < len; i++) c[i] = int(cc[i].real() + 0.5);
  48. return c;
  49. }
  50. const int N = 1e6 + 10;
  51. char s[N], t[N];
  52. bool solve() {
  53. if (scanf("%s%s", s, t) != 2) return false;
  54. int n = strlen(s), m = strlen(t);
  55. vector<int> a(n), b(m);
  56. for (int i = 0; i < n; i++) a[i] = s[n - 1 - i] - '0';
  57. for (int i = 0; i < m; i++) b[i] = t[m - 1 - i] - '0';
  58. auto c = FFT(a, b);
  59. c.resize(c.size() + 5);
  60. int cn = c.size();
  61. for (int i = 1; i < cn; i++) {
  62. c[i] += c[i - 1] / 10;
  63. c[i - 1] %= 10;
  64. }
  65. bool pri = false;
  66. for (int i = cn - 1; i >= 0; i--) {
  67. if (pri || c[i]) {
  68. pri = true;
  69. printf("%d", c[i]);
  70. }
  71. }
  72. if (!pri) printf("0");
  73. printf("\n");
  74. return true;
  75. }
  76. int main() {
  77. while (solve());
  78. return 0;
  79. }

Number-Theoretic Transform

  1. // https://acm.hdu.edu.cn/showproblem.php?pid=1402
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. template<int MOD>
  7. struct ModInt {
  8. public:
  9. constexpr ModInt() {}
  10. constexpr ModInt(int _x) : x(_x) { Ajust(); }
  11. constexpr ModInt(ll _x) : x(_x % MOD) { Ajust(); }
  12. constexpr inline int value() const { return x; }
  13. constexpr inline int inv() const { return Pow(MOD - 2).value(); }
  14. constexpr inline ModInt operator + (const ModInt& rhs) const { return ModInt(x + rhs.value()); }
  15. constexpr inline ModInt operator - (const ModInt& rhs) const { return ModInt(x - rhs.value()); }
  16. constexpr inline ModInt operator * (const ModInt& rhs) const { return ModInt(1LL * x * rhs.value()); }
  17. constexpr inline ModInt operator / (const ModInt& rhs) const { return ModInt(1LL * x * rhs.inv()); }
  18. constexpr inline ModInt operator % (const ModInt& rhs) const { return ModInt(x % rhs.value()); }
  19. constexpr inline ModInt& operator += (const ModInt& rhs) { return (*this = ModInt(x + rhs.value())); }
  20. constexpr inline ModInt& operator -= (const ModInt& rhs) { return (*this = ModInt(x - rhs.value())); }
  21. constexpr inline ModInt& operator *= (const ModInt& rhs) { return (*this = ModInt(1LL * x * rhs.value())); }
  22. constexpr inline ModInt& operator /= (const ModInt& rhs) { return (*this = ModInt(1LL * x * rhs.inv())); }
  23. constexpr inline ModInt& operator %= (const ModInt& rhs) { return (*this = ModInt(x % rhs.value())); }
  24. ModInt Pow(ll n) const {
  25. ll ans = 1, p = x;
  26. while (n) {
  27. if (n & 1) ans = ans * p % MOD;
  28. p = p * p % MOD;
  29. n >>= 1;
  30. }
  31. return ModInt(ans);
  32. }
  33. private:
  34. constexpr inline void Ajust() {
  35. if (x >= 2 * MOD || x < -MOD) x %= MOD;
  36. if (x >= MOD) x -= MOD;
  37. else if (x < 0) x += MOD;
  38. }
  39. int x = 0;
  40. };
  41. constexpr int MOD = 998244353;
  42. typedef ModInt<MOD> mint;
  43. constexpr mint g = 3;
  44. void DFT(vector<mint>& a, int opt) {
  45. int n = a.size();
  46. if (n <= 1) return ;
  47. assert(!(n & (n - 1)));
  48. for (int i = 0, j = 0; i < n - 1; i++) {
  49. if (i < j) swap(a[i], a[j]);
  50. int k = n / 2;
  51. while (j >= k) j -= k, k /= 2;
  52. j += k;
  53. }
  54. for (int i = 2; i <= n; i <<= 1) {
  55. mint wn = g.Pow(1LL * (MOD - 1) / i * ((opt < 0) ? (MOD - 2) : 1));
  56. for (int j = 0; j < n; j += i) {
  57. mint w = 1;
  58. for (int k = j; k < j + i / 2; k++) {
  59. mint u = a[k], v = w * a[k + i / 2];
  60. a[k] = u + v, a[k + i / 2] = u - v;
  61. w *= wn;
  62. }
  63. }
  64. }
  65. if (opt < 0) {
  66. mint invn = mint(n).inv();
  67. for (int i = 0; i < n; i++) a[i] *= invn;
  68. }
  69. }
  70. const int N = 1e6 + 10;
  71. char s[N], t[N];
  72. bool solve() {
  73. if (scanf("%s%s", s, t) != 2) return false;
  74. int n = strlen(s), m = strlen(t);
  75. int len = 1;
  76. while (len < n + m - 1) len <<= 1;
  77. vector<mint> a(len), b(len);
  78. for (int i = 0; i < n; i++) a[n - 1 - i] = s[i] - '0';
  79. for (int i = 0; i < m; i++) b[m - 1 - i] = t[i] - '0';
  80. DFT(a, 1);
  81. DFT(b, 1);
  82. for (int i = 0; i < len; i++) a[i] *= b[i];
  83. DFT(a, -1);
  84. a.resize(a.size() + 5);
  85. for (int i = 1; i < a.size(); i++) {
  86. a[i] += a[i - 1].value() / 10;
  87. a[i - 1] %= 10;
  88. }
  89. bool pri = false;
  90. for (int i = a.size() - 1; i >= 0; i--) {
  91. if (pri || a[i].value() || i == 0) {
  92. printf("%d", a[i].value());
  93. pri = true;
  94. }
  95. }
  96. printf("\n");
  97. return true;
  98. }
  99. int main() {
  100. while (solve());
  101. return 0;
  102. }

Chinese Remainder Theorem

  1. // http://acm.hdu.edu.cn/showproblem.php?pid=3579
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef vector<ll> vii;
  6. void AddMod(ll& a, ll b, ll mod) {
  7. a += b;
  8. if (a >= mod) a -= mod;
  9. }
  10. ll MulMod(ll a, ll b, ll mod) {
  11. a %= mod, b %= mod;
  12. if (a > b) swap(a, b);
  13. ll ans = 0;
  14. while (a) {
  15. if (a & 1) AddMod(ans, b, mod);
  16. AddMod(b, b, mod);
  17. a >>= 1;
  18. }
  19. return ans;
  20. }
  21. void Exgcd(ll a, ll b, ll& x, ll& y) {
  22. if (b == 0) {
  23. x = 1, y = 0;
  24. } else {
  25. Exgcd(b, a % b, x, y);
  26. // b*x+(a%b)*y = 1
  27. // b*x+(a-a/b*b)*y=1
  28. // b*(x-a/b*y)+a*y=1
  29. ll t = y;
  30. y = x - a / b * y;
  31. x = t;
  32. }
  33. }
  34. ll MulInv(ll a, ll mod) {
  35. a %= mod;
  36. ll x, y;
  37. Exgcd(a, mod, x, y);
  38. assert(a * x + mod * y == 1);
  39. x %= mod;
  40. if (x < 0) x += mod;
  41. return x;
  42. }
  43. ll ChineseRemainderTheorem(const vii& mods, const vii& xs) {
  44. assert(mods.size() == xs.size() && mods.size());
  45. const int n = mods.size();
  46. ll M = 1;
  47. for (const ll mod : mods) M *= mod;
  48. ll ans = 0;
  49. for (int i = 0; i < n; i++) {
  50. ll mi = M / mods[i];
  51. AddMod(ans, MulMod(mi * MulInv(mi, mods[i]), xs[i], M), M);
  52. }
  53. return ans;
  54. }
  55. ll ChineseRemainderTheoremCoprimeVersion(const vii& mods, const vii& xs) {
  56. auto Process = [](ll x1, ll mod1, ll x2, ll mod2, ll& x, ll& mod) -> bool {
  57. ll g = __gcd(mod1, mod2);
  58. if ((x1 - x2) % g) return false;
  59. mod1 /= g, mod2 /= g;
  60. mod = mod1 * mod2 * g;
  61. x = MulMod(x2 - x1 + mod, MulInv(mod1, mod2) * mod1, mod);
  62. AddMod(x, x1, mod);
  63. return true;
  64. };
  65. assert(mods.size() == xs.size() && mods.size());
  66. const int n = mods.size();
  67. ll x = xs[0], mod = mods[0];
  68. for (int i = 1; i < n; i++) {
  69. if (!Process(x, mod, xs[i], mods[i], x, mod)) return -1;
  70. }
  71. if (x == 0) x = mod;
  72. return x;
  73. }
  74. ll solve() {
  75. int n;
  76. scanf("%d", &n);
  77. vii mods(n), xs(n);
  78. for (int i = 0; i < n; i++)
  79. scanf("%lld", &mods[i]);
  80. for (int i = 0; i < n; i++)
  81. scanf("%lld", &xs[i]);
  82. return ChineseRemainderTheoremCoprimeVersion(mods, xs);
  83. }
  84. int main() {
  85. int T = 1, t = 0;
  86. scanf("%d", &T);
  87. while (T--) {
  88. printf("Case %d: %lld\n", ++t, solve());
  89. }
  90. return 0;
  91. }

Prime Count

  1. // http://acm.hdu.edu.cn/showproblem.php?pid=5901
  2. // author: yang12138
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. typedef long long ll;
  6. typedef pair<int, int> pii;
  7. namespace primecount {
  8. // 240MB
  9. const int N = 70000;
  10. const int M = 700;
  11. const int PM = 1e7 + 10;
  12. int phi[N][M];
  13. int p[PM / 20], pcnt = 0;
  14. int pc[PM];
  15. void init() {
  16. for (int i = 2; i < PM; i++) {
  17. if (!pc[i]) p[++pcnt] = i;
  18. for (int j = 1; j <= pcnt; j++) {
  19. int u = i * p[j];
  20. if (u >= PM) break;
  21. pc[u] = 1;
  22. if (i % p[j] == 0) break;
  23. }
  24. }
  25. for (int i = 1; i < N; i++) phi[i][0] = i - 1;
  26. for (int i = 1; i < N; i++) {
  27. for (int j = 1; j < M; j++) {
  28. phi[i][j] = phi[i][j-1];
  29. if (i >= p[j] * p[j])
  30. phi[i][j] -= phi[i / p[j]][j-1] - (j - 1);
  31. }
  32. }
  33. for (int i = 2; i < PM; i++)
  34. pc[i] = pc[i-1] + !pc[i];
  35. }
  36. ll Phi(ll n, int m) {
  37. if (n <= 1) return 0;
  38. if (n < N && m < M) return phi[n][m];
  39. if (m == 0) return n - 1;
  40. ll ans = Phi(n, m - 1);
  41. if (n / p[m] >= p[m]) {
  42. ans -= Phi(n / p[m], m - 1) - (m - 1);
  43. }
  44. return ans;
  45. }
  46. int Sqrt(ll n) {
  47. int k = sqrt(n + 0.01);
  48. while (1LL * k * k > n) k--;
  49. while (1LL * (k + 1) * (k + 1) <= n) k++;
  50. return k;
  51. }
  52. int Cbrt(ll n) {
  53. int k = cbrt(n + 0.01);
  54. while (1LL * k * k * k > n) k--;
  55. while (1LL * (k + 1) * (k + 1) * (k + 1) <= n) k++;
  56. return k;
  57. }
  58. // 2 ~ n
  59. // 1e11 350ms
  60. // 1e12 2s
  61. ll PrimeCount(ll n) {
  62. if (n < PM) return pc[n];
  63. int a = pc[Sqrt(n)], b = pc[Cbrt(n)];
  64. ll ans = Phi(n, b);
  65. for (int i = b + 1; i <= a; i++) {
  66. ans -= PrimeCount(n / p[i]);
  67. }
  68. ans += 1LL * b * (a - b) + 1LL * (a - b) * (a - b - 1) / 2;
  69. return ans;
  70. }
  71. } // namespace primecount
  72. void solve() {
  73. ll n;
  74. scanf("%lld", &n);
  75. printf("%lld\n", primecount::PrimeCount(n));
  76. }
  77. int main() {
  78. primecount::init();
  79. int T = 1;
  80. scanf("%d", &T);
  81. while (T--) solve();
  82. return 0;
  83. }

Simplex

  1. // http://acm.hdu.edu.cn/showproblem.php?pid=6248
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const double eps = 1e-8;
  7. const double inf = 1e18;
  8. int dcmp(const double x) {
  9. return fabs(x) < eps ? 0 : (x < 0 ? -1 : 1);
  10. }
  11. /*
  12. target = v + sum(c_i*x_i), i in non_basic
  13. x_i = b_i - sum(A_{ij}*x_j), i in basic, j in non_basic
  14. */
  15. struct Simplex {
  16. public:
  17. Simplex(int n, int m): n(n), m(m), size(n + m + 2), A(size, vector<double>(size, 0)), x(size, 0) {
  18. for (int i = 1; i <= n; i++) non_basic.insert(i);
  19. for (int i = 1; i <= m; i++) basic.insert(n + i);
  20. }
  21. ~Simplex() {}
  22. // variable 1 ~ n
  23. // restrict n + 1 ~ n + m
  24. void AddRestricts(const vector<vector<double>>& restricts) {
  25. assert(restricts.size() == m);
  26. assert(restricts[0].size() == n + 1);
  27. for (int i = 0; i < m; i++) {
  28. for (int j = 0; j <= n; j++) {
  29. A[1 + n + i][j] = restricts[i][j];
  30. }
  31. }
  32. }
  33. void SetTarget(const vector<double>& target) {
  34. assert(target.size() == n + 1);
  35. for (int i = 0; i <= n; i++) A[0][i] = target[i];
  36. }
  37. const vector<double>& GetVariable() { return x; }
  38. double GetAns() { return A[0][0]; }
  39. // -1 no answer, -2 unlimited answer, 0 nomral answer
  40. int Run() {
  41. // print();
  42. if (!Fesible()) {
  43. // printf("fuck, infesible\n");
  44. const auto real_target = A[0];
  45. std::fill(A[0].begin(), A[0].end(), 0);
  46. // target = -x_0
  47. // x_i = b_i - sum(A_{ij}*x_j) + x_0
  48. A[0][size - 1] = -1;
  49. int idx = -1;
  50. for (const int i : basic) {
  51. A[i][size - 1] = -1;
  52. if (idx == -1 || A[i][0] < A[idx][0]) idx = i;
  53. }
  54. non_basic.insert(size - 1);
  55. Pivot(size - 1, idx);
  56. assert(Fesible());
  57. RunSimplex();
  58. if (dcmp(x[size - 1]) != 0) return -1;
  59. if (basic.count(size - 1)) {
  60. for (const int i : non_basic) {
  61. if (dcmp(A[size - 1][i]) != 0) {
  62. Pivot(i, size - 1);
  63. break;
  64. }
  65. }
  66. }
  67. non_basic.erase(size - 1);
  68. A[0] = real_target;
  69. for (const int i : basic) {
  70. if (dcmp(A[0][i]) != 0) {
  71. for (const int j : non_basic) {
  72. A[0][j] -= A[0][i] * A[i][j];
  73. }
  74. A[0][0] += A[0][i] * A[i][0];
  75. }
  76. }
  77. }
  78. assert(Fesible());
  79. // print();
  80. return RunSimplex();
  81. }
  82. void print() const {
  83. printf("target = %.3f + ", A[0][0]);
  84. bool start = true;
  85. for (const int j : non_basic) {
  86. if (!start) printf(" + ");
  87. start = false;
  88. printf("%.3f*x(%d)", A[0][j], j);
  89. }
  90. printf("\n");
  91. for (const int i : basic) {
  92. printf("x(%d) = %.3f - (", i, A[i][0]);
  93. bool start = true;
  94. for (const int j : non_basic) {
  95. if (!start) printf(" + ");
  96. start = false;
  97. printf("%.3f*x(%d)", A[i][j], j);
  98. }
  99. printf(")\n");
  100. }
  101. printf("\n");
  102. }
  103. private:
  104. const int n, m, size;
  105. vector<vector<double>> A;
  106. vector<double> x;
  107. std::set<int> basic, non_basic;
  108. // e nonbasic, l basic
  109. void Pivot(int e, int l) {
  110. assert(dcmp(A[l][e]) != 0);
  111. // printf("Pivot e %d, l %d\n", e, l);
  112. A[e][0] = A[l][0] / A[l][e];
  113. for (const int i : non_basic) {
  114. if (i == e) continue;
  115. A[e][i] = A[l][i] / A[l][e];
  116. }
  117. A[e][l] = 1.0 / A[l][e];
  118. for (const int i : basic) {
  119. if (i == l) continue;
  120. A[i][0] -= A[i][e] * A[e][0];
  121. for (const int j : non_basic) {
  122. if (j == e) continue;
  123. A[i][j] -= A[i][e] * A[e][j];
  124. }
  125. A[i][l] = -A[i][e] * A[e][l];
  126. }
  127. A[0][0] += A[0][e] * A[e][0];
  128. for (const int i : non_basic) {
  129. if (i == e) continue;
  130. A[0][i] -= A[0][e] * A[e][i];
  131. }
  132. A[0][l] = -A[0][e] * A[e][l];
  133. non_basic.erase(e), non_basic.insert(l);
  134. basic.erase(l), basic.insert(e);
  135. }
  136. int Choose(int& e, int& l) {
  137. e = l = -1;
  138. for (const int i : non_basic) {
  139. if (dcmp(A[0][i]) > 0) {
  140. e = i;
  141. break;
  142. }
  143. }
  144. if (e == -1) return -1;
  145. for (const int i : basic) {
  146. if (dcmp(A[i][e]) > 0) {
  147. if (l == -1 || dcmp(A[i][0] / A[i][e] - A[l][0] / A[l][e]) < 0) {
  148. l = i;
  149. }
  150. }
  151. }
  152. if (l == -1) return -2;
  153. return 0;
  154. }
  155. int RunSimplex() {
  156. int e = -1, l = -1, ret = 0;
  157. do {
  158. ret = Choose(e, l);
  159. // printf("Choose ret %d, e %d, l %d\n", ret, e, l);
  160. if (ret == -1) {
  161. // finish
  162. for (const int i : non_basic) x[i] = 0;
  163. for (const int i : basic) x[i] = A[i][0];
  164. ret = 0;
  165. break;
  166. } else if (ret == -2) {
  167. // unlimited answer
  168. for (const int i : non_basic) x[i] = 0;
  169. for (const int i : basic) x[i] = 0;
  170. x[e] = inf;
  171. } else {
  172. // ret == 0
  173. Pivot(e, l);
  174. }
  175. } while (ret == 0);
  176. return ret;
  177. }
  178. bool Fesible() const {
  179. for (const int i : basic) {
  180. if (dcmp(A[i][0]) < 0) return false;
  181. }
  182. return true;
  183. }
  184. };
  185. void solve(const int cas) {
  186. int n, m;
  187. scanf("%d%d", &n, &m);
  188. vector<int> a(n);
  189. for (int i = 0; i < n; i++) scanf("%d", &a[i]);
  190. vector<int> idx(1 << n, 0);
  191. int cnt = 0;
  192. for (int i = 0; i < (1 << n); i++) {
  193. int sum = 0;
  194. for (int j = 0; j < n; j++) {
  195. sum += ((i >> j) & 1) * a[j];
  196. }
  197. if (sum <= m) idx[i] = ++cnt;
  198. }
  199. int v = cnt, e = 2 * n;
  200. Simplex solver(v, e);
  201. vector<vector<double>> restricts(e, vector<double>(v + 1));
  202. vector<double> target(v + 1);
  203. restricts[0][0] = 1.0;
  204. for (int i = 1; i <= v; i++) restricts[0][i] = 1.0;
  205. restricts[1][0] = -1.0;
  206. for (int i = 1; i <= v; i++) restricts[1][i] = -1.0;
  207. for (int i = 0; i + 1 < n; i++) {
  208. for (int mask = 0; mask < (1 << n); mask++) {
  209. if (((mask >> i) & 1) && idx[mask]) {
  210. restricts[2*i+2][idx[mask]] += 1.0;
  211. restricts[2*i+3][idx[mask]] -= 1.0;
  212. if (i == 0) {
  213. target[idx[mask]] = 1.0;
  214. }
  215. }
  216. if (((mask >> (i + 1)) & 1) && idx[mask]) {
  217. restricts[2*i+2][idx[mask]] -= 1.0;
  218. restricts[2*i+3][idx[mask]] += 1.0;
  219. }
  220. }
  221. }
  222. for (int mask = 0; mask < (1 << n); mask++) {
  223. if (((mask >> 0) & 1) && idx[mask]) {
  224. target[idx[mask]] = 1.0;
  225. }
  226. }
  227. solver.AddRestricts(restricts);
  228. solver.SetTarget(target);
  229. solver.Run();
  230. printf("Case #%d: %.8f\n", cas, max(0.0, solver.GetAns()));
  231. }
  232. int main() {
  233. int T = 1, t = 0;
  234. scanf("%d", &T);
  235. while (T--) solve(++t);
  236. return 0;
  237. }

Gaussian Elimination

  1. // http://www.51nod.com/Challenge/Problem.html#problemId=1549
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. const int N = 505;
  5. const double eps = 1e-8;
  6. int Gauss(vector<vector<double>> x, vector<double>& ans) {
  7. int n = x.size();
  8. for (int i = 0; i < n; i++) {
  9. int p = i;
  10. for (int j = i+1; j < n; j++)
  11. if (fabs(x[j][i]) > fabs(x[p][i])) p = j;
  12. if (fabs(x[p][i]) < eps) return -1;
  13. swap(x[i], x[p]);
  14. for (int j = 0; j < n; j++) {
  15. if (i == j) continue;
  16. double factor = x[j][i] / x[i][i];
  17. for (int k = i; k <= n; k++) {
  18. x[j][k] -= x[i][k] * factor;
  19. }
  20. }
  21. }
  22. ans.resize(n);
  23. for (int i = 0; i < n; i++) {
  24. ans[i] = x[i][n] / x[i][i];
  25. for (int j = 0; j < n; j++) {
  26. assert(i == j || fabs(x[i][j]) < eps);
  27. }
  28. }
  29. return 0;
  30. }
  31. void solve() {
  32. // star <= 10 -> 不掉星
  33. // 连胜三局 && star <= 70 -> extra star
  34. int from;
  35. double p;
  36. cin >> from >> p;
  37. int n = 97;
  38. vector<vector<double>> x(3*n, vector<double>(3*n+1, 0.0));
  39. auto ID = [](int star, int win) {
  40. return win * 97 + star;
  41. };
  42. int tot = 3*n;
  43. for (int star = 0; star <= 95; star++) {
  44. for (int win = 0; win <= 2; win++) {
  45. int row = ID(star, win);
  46. x[row][row] = 1.0;
  47. x[row][tot] = 1.0;
  48. if (win == 2 && star <= 70) {
  49. x[row][ID(star+2, 2)] -= p;
  50. } else {
  51. x[row][ID(star+1, min(2, win+1))] -= p;
  52. }
  53. if (star <= 10) {
  54. x[row][ID(star, 0)] -= 1.0-p;
  55. } else {
  56. x[row][ID(max(0, star-1), 0)] -= 1.0-p;
  57. }
  58. }
  59. }
  60. x[ID(96, 0)][ID(96, 0)] = 1.0;
  61. x[ID(96, 1)][ID(96, 1)] = 1.0;
  62. x[ID(96, 2)][ID(96, 2)] = 1.0;
  63. vector<double> ans;
  64. int ret = Gauss(x, ans);
  65. assert(ret == 0);
  66. printf("%.10f\n", ans[ID(96-from, 0)]);
  67. }
  68. int main() {
  69. solve();
  70. return 0;
  71. }

Linear Basis

  1. // http://acm.hdu.edu.cn/showproblem.php?pid=3949
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. typedef vector<ll> vii;
  7. const int B = 60;
  8. bool Contain(ll v, int b) { return (v >> b) & 1; }
  9. vii LinearBasis(vii v) {
  10. vii ans;
  11. for (int i = B - 1, r = 0; i >= 0 && r < v.size(); i--) {
  12. int pos = -1;
  13. for (int j = r; j < v.size(); j++) {
  14. if (Contain(v[j], i)) { pos = j; break; }
  15. }
  16. if (pos == -1) continue;
  17. swap(v[r], v[pos]);
  18. for (int j = r + 1; j < v.size(); j++)
  19. if (Contain(v[j], i)) v[j] ^= v[r];
  20. for (ll& t : ans)
  21. if (Contain(t, i)) t ^= v[r];
  22. ans.push_back(v[r++]);
  23. }
  24. return ans;
  25. }
  26. void print(ll v) {
  27. for (int i = B - 1; i >= 0; i--) {
  28. printf("%d", Contain(v, i) ? 1 : 0);
  29. }
  30. printf("\n");
  31. }
  32. void solve() {
  33. int n;
  34. scanf("%d", &n);
  35. vii v(n);
  36. for (int i = 0; i < n; i++) scanf("%lld", &v[i]);
  37. vii v2 = LinearBasis(v);
  38. bool sub = v2.size() < v.size();
  39. // for (auto i : v2) print(i);
  40. int Q;
  41. scanf("%d", &Q);
  42. while (Q--) {
  43. ll k;
  44. scanf("%lld", &k);
  45. k -= sub;
  46. if (k == 0) {
  47. printf("0\n");
  48. continue;
  49. }
  50. if (k >= (1LL << v2.size())) {
  51. printf("-1\n");
  52. continue;
  53. }
  54. ll ans = 0;
  55. for (int i = 0; i < v2.size(); i++) {
  56. if (Contain(k, i)) ans ^= v2.end()[-i-1];
  57. }
  58. printf("%lld\n", ans);
  59. }
  60. }
  61. int main() {
  62. int T = 1, t = 0;
  63. scanf("%d", &T);
  64. while (T--) {
  65. printf("Case #%d:\n", ++t);
  66. solve();
  67. }
  68. return 0;
  69. }

Others

Digit DP

  1. // http://www.51nod.com/Challenge/Problem.html#problemId=1232
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const int MOD = 2520;
  7. ll dp[20][MOD + 1][50];
  8. int idx[MOD + 1];
  9. int c[MOD + 1][10];
  10. int num[20];
  11. ll DP(int len, int left, int lcm, bool flag) {
  12. if (len == 0) return lcm && (left % lcm == 0);
  13. ll& tdp = dp[len][left][idx[lcm]];
  14. if (flag && tdp >= 0) return tdp;
  15. ll ans = 0;
  16. for (int i = flag ? 9 : num[len]; i >= 0; i--) {
  17. ans += DP(len-1, (left*10+i) % MOD , c[lcm][i], flag || (i < num[len]));
  18. }
  19. if (flag) tdp = ans;
  20. return ans;
  21. }
  22. ll CalcAns(ll n) {
  23. if (n <= 0) return 0;
  24. int len = 0;
  25. while (n) {
  26. num[++len] = n % 10;
  27. n /= 10;
  28. }
  29. return DP(len, 0, 0, 0);
  30. }
  31. void solve() {
  32. int cnt = 0;
  33. idx[0] = cnt++;
  34. for (int i = 1; i <= MOD; i++)
  35. if (MOD % i == 0) idx[i] = cnt++;
  36. // cout << cnt << endl;
  37. c[0][0] = 0;
  38. for (int i = 1; i <= 9; i++) c[0][i] = i;
  39. for (int i = 1; i <= MOD; i++) {
  40. c[i][0] = i;
  41. for (int j = 1; j <= 9; j++) {
  42. c[i][j] = i * j / __gcd(i, j);
  43. }
  44. }
  45. int Q;
  46. scanf("%d", &Q);
  47. while (Q--) {
  48. ll l, r;
  49. scanf("%lld%lld", &l, &r);
  50. printf("%lld\n", CalcAns(r) - CalcAns(l - 1));
  51. }
  52. }
  53. int main() {
  54. memset(dp, -1, sizeof(dp));
  55. int T = 1;
  56. // scanf("%d", &T);
  57. while (T--) solve();
  58. return 0;
  59. }

Line And Circle

  1. // https://leetcode.cn/contest/autox2023/problems/TcdlJS/
  2. class Solution {
  3. public:
  4. typedef long long ll;
  5. struct Line {
  6. ll x1, y1, x2, y2;
  7. Line(ll x1, ll y1, ll x2, ll y2) : x1(x1), y1(y1), x2(x2), y2(y2) {
  8. // if (x1 > x2) swap(x1, x2), swap(y1, y2);
  9. // else if (x1 == x2 && y1 > y2) swap(y1, y2);
  10. }
  11. array<ll, 3> Get() const {
  12. // y-y1 = (y2-y1)/(x2-x1)*(x-x1)
  13. // (y-y1)*(x2-x1)=(y2-y1)*(x-x1)
  14. ll a = (y2-y1), b = (x1-x2), c = -x1*(y2-y1)+y1*(x2-x1);
  15. ll g = __gcd(a, __gcd(b, c));
  16. a /= g, b /= g, c /= g;
  17. if (a < 0) a = -a, b = -b, c = -c;
  18. else if (a == 0 && b < 0) b = -b, c = -c;
  19. return {a, b, c};
  20. }
  21. bool Contain(ll x, ll y) const {
  22. return x >= min(x1, x2) && x <= max(x1, x2) && y >= min(y1, y2) && y <= max(y1, y2);
  23. }
  24. bool Inter(const Line& rhs) const {
  25. auto l = Get(), r = rhs.Get();
  26. if (l[0]*r[1] == r[0]*l[1]) {
  27. if (l[0] == r[0] && l[1] == r[1] && l[2] == r[2]) {
  28. return Contain(rhs.x1, rhs.y1) || Contain(rhs.x2, rhs.y2) || rhs.Contain(x1, y1) || rhs.Contain(x2,y2);
  29. }
  30. return false;
  31. }
  32. if (r[0] == 0) swap(l, r);
  33. assert(r[0]);
  34. double y = 1.0 * (l[0]*r[2]-r[0]*l[2]) / (r[0]*l[1] - l[0]*r[1]);
  35. double x = 1.0 * (-r[2]-r[1]*y)/r[0];
  36. static const double eps = 1e-8;
  37. if (y > min(y1, y2) - eps && y < max(y1, y2) + eps &&
  38. y > min(rhs.y1, rhs.y2) - eps && y < max(rhs.y1, rhs.y2) + eps &&
  39. x > min(x1, x2) - eps && x < max(x1, x2) + eps &&
  40. x > min(rhs.x1, rhs.x2) - eps && x < max(rhs.x1, rhs.x2) + eps)
  41. return true;
  42. return false;
  43. }
  44. };
  45. struct Circle {
  46. ll x, y, r;
  47. Circle(ll x, ll y, ll r) : x(x), y(y), r(r) {}
  48. bool Contain(const Circle& rhs) const {
  49. return (x-rhs.x)*(x-rhs.x)+(y-rhs.y)*(y-rhs.y) < (r-rhs.r)*(r-rhs.r);
  50. }
  51. bool Separated(const Circle& rhs) const {
  52. return (x-rhs.x)*(x-rhs.x)+(y-rhs.y)*(y-rhs.y) > (r+rhs.r)*(r+rhs.r);
  53. }
  54. bool Inter(const Circle& rhs) const {
  55. if (Contain(rhs) || rhs.Contain(*this) || Separated(rhs)) return false;
  56. return true;
  57. }
  58. static int sig(ll x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); }
  59. bool Inter(const Line& rhs) const {
  60. ll d1 = (x-rhs.x1)*(x-rhs.x1)+(y-rhs.y1)*(y-rhs.y1) - r*r;
  61. ll d2 = (x-rhs.x2)*(x-rhs.x2)+(y-rhs.y2)*(y-rhs.y2) - r*r;
  62. if (sig(d1)*sig(d2) <= 0) return true;
  63. if (d1 < 0 && d2 < 0) return false;
  64. ll a1 = rhs.x2-rhs.x1, b1 = rhs.y2-rhs.y1, c1 = x*(rhs.x1-rhs.x2)+y*(rhs.y1-rhs.y2);
  65. ll a2 = rhs.y2-rhs.y1, b2 = rhs.x1-rhs.x2, c2 = rhs.x1*(rhs.y1-rhs.y2)+rhs.y1*(rhs.x2-rhs.x1);
  66. if (a2 == 0) swap(a1, a2), swap(b1, b2), swap(c1, c2);
  67. assert(a2);
  68. double y0 = 1.0 * (a1*c2-a2*c1) / (a2*b1-a1*b2);
  69. // printf("y0 %.5f, y1 %lld, y2 %lld\n", y0, rhs.y1, rhs.y2);
  70. static const double eps = 1e-8;
  71. if (y0 > min(rhs.y1, rhs.y2) - eps && y0 < max(rhs.y1, rhs.y2) + eps) {
  72. double x0 = 1.0*(-c2-b2*y0)/a2;
  73. // printf("%.10f %.10f\n", x0, y0);
  74. if ((x-x0)*(x-x0)+(y-y0)*(y-y0) < r*r+eps) return true;
  75. }
  76. return false;
  77. }
  78. };
  79. void dfs(int u, const vector<vector<int>>& vis, vector<int>& id, int tmp) {
  80. id[u] = tmp;
  81. for (int i = 0; i < vis.size(); i++) {
  82. if (vis[u][i] && id[i] < 0) {
  83. dfs(i, vis, id, tmp);
  84. }
  85. }
  86. }
  87. vector<bool> antPass(vector<vector<int>>& g, vector<vector<int>>& path) {
  88. int n = g.size();
  89. vector<pair<Line, int>> lines;
  90. vector<pair<Circle, int>> cirs;
  91. for (int i = 0; i < n; i++) {
  92. const auto& v = g[i];
  93. if (v.size() == 4) {
  94. Line line(v[0], v[1], v[2], v[3]);
  95. lines.emplace_back(line, i);
  96. } else if (v.size() == 3) {
  97. Circle cir(v[0], v[1], v[2]);
  98. cirs.emplace_back(cir, i);
  99. } else {
  100. assert(false);
  101. }
  102. }
  103. vector<vector<int>> vis(n, vector<int>(n, 0));
  104. for (const auto& [l1, i] : lines) {
  105. for (const auto& [l2, j] : lines) {
  106. vis[i][j] = l1.Inter(l2);
  107. }
  108. }
  109. for (const auto& [c1, i] : cirs) {
  110. for (const auto& [c2, j] : cirs) {
  111. vis[i][j] = c1.Inter(c2);
  112. }
  113. }
  114. for (const auto& [l, i] : lines) {
  115. for (const auto& [c, j] : cirs) {
  116. vis[i][j] = vis[j][i] = c.Inter(l);
  117. }
  118. }
  119. for (int i = 0; i < n; i++) {
  120. for (int j = 0; j < n; j++) {
  121. assert(vis[i][j] == vis[j][i]);
  122. // printf("%d %d %d\n", i, j, vis[i][j]);
  123. }
  124. }
  125. vector<int> id(n, -1);
  126. int tmp = 0;
  127. for (int i = 0; i < n; i++) {
  128. if (id[i] < 0) {
  129. dfs(i, vis, id, tmp++);
  130. }
  131. }
  132. vector<bool> ans;
  133. for (auto& q : path) {
  134. if (id[q[0]] == id[q[1]]) ans.push_back(true);
  135. else ans.push_back(false);
  136. }
  137. return ans;
  138. }
  139. };

整体二分

  1. // https://acm.hdu.edu.cn/showproblem.php?pid=5412
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. typedef pair<int, int> pii;
  6. const int N = 3e5+10;
  7. struct Bits {
  8. int bits[N], n;
  9. void Reset(int n) {
  10. std::fill(bits, bits + n + 1, 0);
  11. this->n = n;
  12. }
  13. void Add(int i, int d) {
  14. while (i <= n) {
  15. bits[i] += d;
  16. i += i & -i;
  17. }
  18. }
  19. int Sum(int i) {
  20. int ans = 0;
  21. while (i) {
  22. ans += bits[i];
  23. i -= i & -i;
  24. }
  25. return ans;
  26. }
  27. } bt;
  28. struct Query {
  29. int op;
  30. int l, r, k, id;
  31. int flag;
  32. void scan(int id) {
  33. scanf("%d", &op);
  34. if (op == 1) scanf("%d%d", &l, &k);
  35. else scanf("%d%d%d", &l, &r, &k);
  36. this->id = id;
  37. flag = 1;
  38. }
  39. } Q[N], Q1[N], Q2[N];
  40. int ans[N], tmp[N];
  41. void solve(int l, int r, int a, int b) {
  42. if (a > b) return ;
  43. if (l == r) {
  44. for (int i = a; i <= b; i++) {
  45. if (Q[i].op == 2)
  46. ans[Q[i].id] = l;
  47. }
  48. return ;
  49. }
  50. int m = (l + r) >> 1;
  51. for (int i = a; i <= b; i++) {
  52. if (Q[i].op == 1 && Q[i].k <= m) {
  53. bt.Add(Q[i].l, Q[i].flag);
  54. } else if (Q[i].op == 2) {
  55. tmp[i] = bt.Sum(Q[i].r) - bt.Sum(Q[i].l-1);
  56. }
  57. }
  58. for (int i = a; i <= b; i++) {
  59. if (Q[i].op == 1 && Q[i].k <= m) {
  60. bt.Add(Q[i].l, -Q[i].flag);
  61. }
  62. }
  63. int t1 = 0, t2 = 0;
  64. for (int i = a; i <= b; i++) {
  65. if (Q[i].op == 1) {
  66. if (Q[i].k <= m) Q1[t1++] = Q[i];
  67. else Q2[t2++] = Q[i];
  68. } else {
  69. if (tmp[i] >= Q[i].k) Q1[t1++] = Q[i];
  70. else {
  71. Q2[t2++] = Q[i];
  72. Q2[t2-1].k -= tmp[i];
  73. }
  74. }
  75. }
  76. assert(a + t1 + t2 - 1 == b);
  77. for (int i = a; i < a + t1; i++) Q[i] = Q1[i-a];
  78. for (int i = a + t1; i < a + t1 + t2; i++) Q[i] = Q2[i-a-t1];
  79. solve(l, m, a, a + t1 - 1);
  80. solve(m+1, r, a + t1, a + t1 + t2 - 1);
  81. }
  82. int b[N], m;
  83. int pre[N], n;
  84. int GetRank(int x) {
  85. return lower_bound(b+1, b+m+1, x) - b;
  86. }
  87. bool solve() {
  88. if (scanf("%d", &n) != 1) return false;
  89. m = 0;
  90. int tn = 0;
  91. for (int i = 1; i <= n; i++) {
  92. int x;
  93. scanf("%d", &x);
  94. auto& query = Q[++tn];
  95. query.op = 1, query.l = i, query.k = x, query.flag = 1;
  96. b[++m] = x;
  97. pre[query.l] = x;
  98. }
  99. int q;
  100. scanf("%d", &q);
  101. for (int i = 1; i <= q; i++) {
  102. auto& query = Q[++tn];
  103. query.scan(i);
  104. if (query.op == 1) {
  105. b[++m] = query.k;
  106. auto& query2 = Q[++tn];
  107. query2 = query;
  108. query2.k = pre[query.l];
  109. query2.flag = -1;
  110. pre[query.l] = query.k;
  111. swap(query, query2);
  112. }
  113. }
  114. sort(b+1, b+m+1);
  115. // m = unique(b+1, b+m+1)-b-1;
  116. for (int i = 1; i <= tn; i++)
  117. if (Q[i].op == 1)
  118. Q[i].k = GetRank(Q[i].k);
  119. bt.Reset(n);
  120. std::fill(ans+1, ans+q+1, -1);
  121. solve(1, m, 1, tn);
  122. for (int i = 1; i <= q; i++) {
  123. if (ans[i] > 0) printf("%d\n", b[ans[i]]);
  124. }
  125. return true;
  126. }
  127. int main() {
  128. while (solve());
  129. return 0;
  130. }

Fast IO

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef pair<int, int> pii;
  5. struct FastIO {
  6. static const int BUFFER_SIZE = (1 << 24);
  7. char buffer[BUFFER_SIZE];
  8. char *head = nullptr, *tail = nullptr;
  9. void ReadBuffer() {
  10. int len = fread(buffer, 1, BUFFER_SIZE, stdin);
  11. head = buffer, tail = buffer + len;
  12. }
  13. char getch() {
  14. if (head == tail) ReadBuffer();
  15. if (head == tail) return 0;
  16. return *head++;
  17. }
  18. template<class T>
  19. void Read(T& n) {
  20. n = 0;
  21. bool flag = false;
  22. char ch = getch();
  23. while (!isdigit(ch) && ch != '-') ch = getch();
  24. if (ch == '-') flag = true, ch = getch();
  25. do {
  26. n = 10 * n + ch - '0';
  27. ch = getch();
  28. } while (isdigit(ch));
  29. if (flag) n = -n;
  30. }
  31. template<class T>
  32. void Print(const T n) const {
  33. if (n < 0) {
  34. putchar('-');
  35. Print(-n);
  36. return ;
  37. }
  38. if (n > 9) Print(n / 10);
  39. putchar(n % 10 + '0');
  40. }
  41. } io;
  42. void solve() {
  43. int n;
  44. io.Read(n);
  45. io.Print(n);
  46. printf("\n");
  47. while (n--) {
  48. ll x;
  49. io.Read(x);
  50. io.Print(x);
  51. printf("\n");
  52. }
  53. }
  54. void solve2() {
  55. int n;
  56. scanf("%d", &n);
  57. printf("%d\n", n);
  58. while (n--) {
  59. ll x;
  60. scanf("%lld", &x);
  61. printf("%lld\n", x);
  62. }
  63. }
  64. int main(int argc, char** argv) {
  65. int t = atoi(argv[1]);
  66. if (t == 1) solve();
  67. else solve2();
  68. return 0;
  69. }

vimrc

  1. set nu
  2. syntax on
  3. set autoindent
  4. set cindent
  5. set cursorline
  6. set mouse=a
  7. set ts=4
  8. set expandtab
  9. set shiftwidth=4
  10. set hlsearch
  11. set ignorecase
  12. if has("autocmd")
  13. au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
  14. endif
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注