[关闭]
@qq290637843 2021-01-30T13:19:08.000000Z 字数 25524 阅读 501

2019南京

题目见https://www.jisuanke.com/contest/5528/challenges

A、A Hard Problem

实际就是问最多选多少个数使得两两不为倍数关系。首先,选最大的是可行的。关于最大性,注意每个奇数所对应的所有中只能选一个,于是不可能选超过

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. ul T;
  7. ul n;
  8. int main()
  9. {
  10. std::scanf("%u", &T);
  11. for (ul Case = 1; Case <= T; ++Case) {
  12. std::scanf("%u", &n);
  13. std::printf("%u\n", (n + 1 >> 1) + 1);
  14. }
  15. return 0;
  16. }

B、Chessboard

倒着考虑,就是说每走一步挖掉一个格子,要求任何时刻剩余的格子构成的区域是满足要求的。那么显然,一开始只能选择从四角挖,接着,只能沿着剩余区域的一边走,不到端点不能转弯,于是乎任何时候都是从剩余区域挖掉一条边然后留下一个长方形。一开始的选角数量等于,接下来就是简单的次作为删横边,次作为删竖边。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul mod = 1e9 + 7;
  7. ul mul(ul a, ul b)
  8. {
  9. return ull(a) * ull(b) % mod;
  10. }
  11. void exgcd(li a, li b, li& x, li& y)
  12. {
  13. if (b) {
  14. exgcd(b, a % b, y, x);
  15. y -= a / b * x;
  16. } else {
  17. x = 1;
  18. y = 0;
  19. }
  20. }
  21. ul inverse(ul a)
  22. {
  23. li x, y;
  24. exgcd(a, mod, x, y);
  25. return x < 0 ? x + li(mod) : x;
  26. }
  27. ul T;
  28. ul n, m;
  29. const ul maxn = 1e6;
  30. const ul maxm = 1e6;
  31. ul fac[maxn + maxm + 1];
  32. ul fiv[maxn + maxm + 1];
  33. int main()
  34. {
  35. fac[0] = 1;
  36. for (ul i = 1; i <= maxn + maxm; ++i) {
  37. fac[i] = mul(fac[i - 1], i);
  38. }
  39. fiv[maxn + maxm] = inverse(fac[maxn + maxm]);
  40. for (ul i = maxn + maxm; i >= 1; --i) {
  41. fiv[i - 1] = mul(fiv[i], i);
  42. }
  43. std::scanf("%u", &T);
  44. for (ul Case = 1; Case <= T; ++Case) {
  45. std::scanf("%u%u", &n, &m);
  46. std::printf("%u\n", mul(mul((n >= 2) + 1, (m >= 2) + 1), mul(fac[n + m - 2], mul(fiv[n - 1], fiv[m - 1]))));
  47. }
  48. return 0;
  49. }

C、Digital Path

简单动态规划

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using pulul = std::pair<ul, ul>;
  7. using plipulul = std::pair<li, pulul>;
  8. const ul mod = 1e9 + 7;
  9. ul plus(ul a, ul b)
  10. {
  11. return a + b < mod ? a + b : a + b - mod;
  12. }
  13. ul n, m;
  14. const ul maxn = 1000;
  15. const ul maxm = 1000;
  16. ul ans[maxn + 1][maxm + 1][5];
  17. ul out = 0;
  18. li val[maxn + 2][maxm + 2];
  19. std::vector<plipulul> pos;
  20. int main()
  21. {
  22. std::scanf("%u%u", &n, &m);
  23. for (ul j = 1; j <= m; ++j) {
  24. val[0][j] = val[n + 1][j] = 1e9;
  25. }
  26. for (ul i = 1; i <= n; ++i) {
  27. val[i][0] = val[i][m + 1] = 1e9;
  28. }
  29. for (ul i = 1; i <= n; ++i) {
  30. for (ul j = 1; j <= m; ++j) {
  31. std::scanf("%d", &val[i][j]);
  32. pos.push_back(plipulul(val[i][j], pulul(i, j)));
  33. }
  34. }
  35. std::sort(pos.begin(), pos.end());
  36. for (const auto& p : pos) {
  37. const auto& curr = p.second;
  38. bool ishead = true;
  39. bool istail = true;
  40. for (const auto& prev : {pulul(curr.first + 1, curr.second), pulul(curr.first, curr.second + 1), pulul(curr.first - 1, curr.second), pulul(curr.first, curr.second - 1)}) {
  41. if (val[prev.first][prev.second] == p.first - 1) {
  42. ishead = false;
  43. for (ul i = 1; i <= 4; ++i) {
  44. ans[curr.first][curr.second][std::min(i + 1, ul(4))] = plus(ans[curr.first][curr.second][std::min(i + 1, ul(4))], ans[prev.first][prev.second][i]);
  45. }
  46. }
  47. if (val[prev.first][prev.second] == p.first + 1) {
  48. istail = false;
  49. }
  50. }
  51. if (ishead) {
  52. ans[curr.first][curr.second][1] = 1;
  53. }
  54. if (istail) {
  55. out = plus(out, ans[curr.first][curr.second][4]);
  56. }
  57. }
  58. std::printf("%u\n", out);
  59. return 0;
  60. }

D、Holes

首先将所有洞的出边全部砍掉。
于是实际就是要对每一个,考虑分母和分子该怎么求。
由于


,那么上二式即为
这是两个元稀疏方程,所以可以解决,但还是大了。
每个点都对应着两个方程。现在考虑对满足如下性质的点的任意取值:是第一行的,或者是个洞。接着,其余点都可以根据其正上方挨着那个点所对应的方程递推出一个值。现在得到的这个显然满足以下这些方程:既不是最后一行的,也不是洞正上方挨着的点,这些点所对应的方程。而可能不满足的方程数正好就是任意取值的那些点的数量。换言之,就是用那些“自变点”的表示出“因变点”的,并用剩余方程解出“自变点”的值。而这个递推过程可以完成,故实际最终只需要解两个元的线性方程组,故最终时间复杂度

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using pulul = std::pair<ul, ul>;
  7. pulul operator+(const pulul& a, const pulul& b)
  8. {
  9. return pulul(a.first + b.first, a.second + b.second);
  10. }
  11. const ul mod = 1e9 + 7;
  12. ul plus(ul a, ul b)
  13. {
  14. return a + b < mod ? a + b : a + b - mod;
  15. }
  16. ul minus(ul a, ul b)
  17. {
  18. return a < b ? a + mod - b : a - b;
  19. }
  20. ul mul(ul a, ul b)
  21. {
  22. return ull(a) * ull(b) % mod;
  23. }
  24. void exgcd(li a, li b, li& x, li& y)
  25. {
  26. if (b) {
  27. exgcd(b, a % b, y, x);
  28. y -= a / b * x;
  29. } else {
  30. x = 1;
  31. y = 0;
  32. }
  33. }
  34. ul inverse(ul a)
  35. {
  36. li x, y;
  37. exgcd(a, mod, x, y);
  38. return x < 0 ? x + li(mod) : x;
  39. }
  40. ul T;
  41. ul n;
  42. ul k;
  43. ul tot;
  44. const ul maxn = 200;
  45. const ul maxk = 200;
  46. const ul maxtot = maxk + maxn;
  47. bool ishole[maxn + 1][maxn + 2];
  48. pulul holes[maxk + 1];
  49. pulul from[maxk + maxn + 1];
  50. ul fromid[maxn + 1][maxn + 2];
  51. class val_t {
  52. public:
  53. ul dx[maxtot + 1];
  54. ul dy[maxtot + 1];
  55. ul c;
  56. void init()
  57. {
  58. std::memset(dx + 1, 0, sizeof(ul) * tot);
  59. std::memset(dy + 1, 0, sizeof(ul) * tot);
  60. c = 0;
  61. }
  62. };
  63. val_t operator+(const val_t& a, const val_t& b)
  64. {
  65. static val_t ret;
  66. for (ul i = 1; i <= tot; ++i) {
  67. ret.dx[i] = plus(a.dx[i], b.dx[i]);
  68. }
  69. for (ul i = 1; i <= tot; ++i) {
  70. ret.dy[i] = plus(a.dy[i], b.dy[i]);
  71. }
  72. ret.c = plus(a.c, b.c);
  73. return ret;
  74. }
  75. val_t operator-(const val_t& a, const val_t& b)
  76. {
  77. static val_t ret;
  78. for (ul i = 1; i <= tot; ++i) {
  79. ret.dx[i] = minus(a.dx[i], b.dx[i]);
  80. }
  81. for (ul i = 1; i <= tot; ++i) {
  82. ret.dy[i] = minus(a.dy[i], b.dy[i]);
  83. }
  84. ret.c = minus(a.c, b.c);
  85. return ret;
  86. }
  87. val_t operator*(const val_t& a, ul b)
  88. {
  89. static val_t ret;
  90. for (ul i = 1; i <= tot; ++i) {
  91. ret.dx[i] = mul(a.dx[i], b);
  92. }
  93. for (ul i = 1; i <= tot; ++i) {
  94. ret.dy[i] = mul(a.dy[i], b);
  95. }
  96. ret.c = mul(a.c, b);
  97. return ret;
  98. }
  99. val_t operator/(const val_t& a, ul b)
  100. {
  101. return a * inverse(b);
  102. }
  103. ul deg[maxn + 1][maxn + 2];
  104. template<typename T>
  105. T& at(T v[][maxn + 2], const pulul& p)
  106. {
  107. return v[p.first][p.second];
  108. }
  109. val_t ans[maxn + 1][maxn + 2][2];
  110. pulul s;
  111. ul a[maxtot + 1][maxtot + 1];
  112. ul b[maxtot + 1];
  113. void solve(ul a[][maxtot + 1], ul b[], ul x[])
  114. {
  115. for (ul i = 1; i <= tot; ++i) {
  116. if (!a[i][i]) {
  117. for (ul j = i + 1; j <= tot; ++j) {
  118. if (a[j][i]) {
  119. for (ul k = i; k <= tot; ++k) {
  120. std::swap(a[i][k], a[j][k]);
  121. }
  122. std::swap(b[i], b[j]);
  123. break;
  124. }
  125. }
  126. }
  127. ul t = inverse(a[i][i]);
  128. for (ul j = i; j <= tot; ++j) {
  129. a[i][j] = mul(a[i][j], t);
  130. }
  131. b[i] = mul(b[i], t);
  132. for (ul j = 1; j <= tot; ++j) {
  133. if (j == i) {
  134. continue;
  135. }
  136. t = a[j][i];
  137. if (t) {
  138. for (ul k = i; k <= tot; ++k) {
  139. a[j][k] = minus(a[j][k], mul(t, a[i][k]));
  140. }
  141. b[j] = minus(b[j], mul(t, b[i]));
  142. }
  143. }
  144. }
  145. std::memcpy(x + 1, b + 1, sizeof(ul) * tot);
  146. }
  147. ul x[maxtot + 1];
  148. ul y[maxtot + 1];
  149. int main()
  150. {
  151. std::scanf("%u", &T);
  152. for (ul Case = 1; Case <= T; ++Case) {
  153. std::scanf("%u%u", &n, &k);
  154. for (ul i = 0; i <= n; ++i) {
  155. std::memset(ishole[i], false, sizeof(bool) * (n + 2));
  156. }
  157. deg[1][1] = 2;
  158. for (ul j = 2; j <= n - 1; ++j) {
  159. deg[1][j] = 3;
  160. }
  161. deg[1][n] = 2;
  162. for (ul i = 2; i <= n - 1; ++i) {
  163. deg[i][1] = 3;
  164. for (ul j = 2; j <= n - 1; ++j) {
  165. deg[i][j] = 4;
  166. }
  167. deg[i][n] = 3;
  168. }
  169. deg[n][1] = 2;
  170. for (ul j = 2; j <= n - 1; ++j) {
  171. deg[n][j] = 3;
  172. }
  173. deg[n][n] = 2;
  174. for (ul i = 1; i <= k; ++i) {
  175. std::scanf("%u%u", &holes[i].first, &holes[i].second);
  176. at(ishole, holes[i]) = true;
  177. }
  178. std::scanf("%u%u", &s.first, &s.second);
  179. for (ul i = 1; i <= k; ++i) {
  180. at(fromid, holes[i]) = i;
  181. from[i] = holes[i];
  182. }
  183. tot = k;
  184. for (ul j = 1; j <= n; ++j) {
  185. if (!ishole[1][j]) {
  186. ++tot;
  187. fromid[1][j] = tot;
  188. from[tot] = pulul(1, j);
  189. }
  190. }
  191. for (ul i = 1; i <= tot; ++i) {
  192. at(ans, from[i])[0].init();
  193. at(ans, from[i])[1].init();
  194. at(ans, from[i])[0].dx[i] = 1;
  195. at(ans, from[i])[1].dy[i] = 1;
  196. }
  197. for (pulul curr(2, 1); curr.first <= n; ++curr.first) {
  198. for (curr.second = 1; curr.second <= n; ++curr.second) {
  199. if (at(ishole, curr)) {
  200. continue;
  201. }
  202. pulul up = curr + pulul(-1, 0);
  203. at(ans, curr)[0] = at(ans, up)[0];
  204. at(ans, curr)[1] = at(ans, up)[1] - at(ans, up)[0];
  205. for (const auto& next : {up + pulul(0, 1), up + pulul(-1, 0), up + pulul(0, -1)}) {
  206. if (next.first < 1 || next.second < 1 || next.second > n) {
  207. continue;
  208. }
  209. if (at(ishole, next)) {
  210. continue;
  211. }
  212. at(ans, curr)[0] = at(ans, curr)[0] - at(ans, next)[0] / at(deg, next);
  213. at(ans, curr)[1] = at(ans, curr)[1] - at(ans, next)[1] / at(deg, next);
  214. if (next == s) {
  215. at(ans, curr)[0].c = minus(at(ans, curr)[0].c, inverse(at(deg, s)));
  216. }
  217. }
  218. if (curr == s) {
  219. at(ans, curr)[0].c = minus(at(ans, curr)[0].c, inverse(at(deg, s)));
  220. }
  221. at(ans, curr)[0] = at(ans, curr)[0] * at(deg, curr);
  222. at(ans, curr)[1] = at(ans, curr)[1] * at(deg, curr);
  223. }
  224. }
  225. ul eqtot = 0;
  226. for (pulul curr(1, 1); curr.first <= n; ++curr.first) {
  227. for (curr.second = 1; curr.second <= n; ++curr.second) {
  228. if (curr.first == n || at(ishole, curr + pulul(1, 0))) {
  229. ++eqtot;
  230. val_t tmp = at(ans, curr)[0];
  231. for (const auto& next : {curr + pulul(0, 1), curr + pulul(-1, 0), curr + pulul(0, -1)}) {
  232. if (next.first < 1 || next.second < 1 || next.second > n) {
  233. continue;
  234. }
  235. if (at(ishole, next)) {
  236. continue;
  237. }
  238. tmp = tmp - at(ans, next)[0] / at(deg, next);
  239. if (next == s) {
  240. tmp.c = minus(tmp.c, inverse(at(deg, s)));
  241. }
  242. }
  243. std::memcpy(a[eqtot] + 1, tmp.dx + 1, sizeof(ul) * tot);
  244. b[eqtot] = minus(0, tmp.c);
  245. }
  246. }
  247. }
  248. solve(a, b, x);
  249. eqtot = 0;
  250. for (pulul curr(1, 1); curr.first <= n; ++curr.first) {
  251. for (curr.second = 1; curr.second <= n; ++curr.second) {
  252. if (curr.first == n || at(ishole, curr + pulul(1, 0))) {
  253. ++eqtot;
  254. val_t tmp = at(ans, curr)[1] - at(ans, curr)[0];
  255. for (const auto& next : {curr + pulul(0, 1), curr + pulul(-1, 0), curr + pulul(0, -1)}) {
  256. if (next.first < 1 || next.second < 1 || next.second > n) {
  257. continue;
  258. }
  259. if (at(ishole, next)) {
  260. continue;
  261. }
  262. tmp = tmp - at(ans, next)[1] / at(deg, next);
  263. }
  264. std::memcpy(a[eqtot] + 1, tmp.dy + 1, sizeof(ul) * tot);
  265. b[eqtot] = minus(0, tmp.c);
  266. for (ul i = 1; i <= tot; ++i) {
  267. b[eqtot] = minus(b[eqtot], mul(x[i], tmp.dx[i]));
  268. }
  269. }
  270. }
  271. }
  272. solve(a, b, y);
  273. for (ul i = 1; i <= k; ++i) {
  274. if (i != 1) {
  275. std::putchar(' ');
  276. }
  277. if (!x[i]) {
  278. std::printf("GG");
  279. } else {
  280. std::printf("%u", mul(y[i], inverse(x[i])));
  281. }
  282. }
  283. std::putchar('\n');
  284. }
  285. return 0;
  286. }

E、Observation

在正整数上是一个积性函数,证明见https://projecteuclid.org/download/pdf_1/euclid.bams/1183503695

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. const ul sp = 3162277;
  7. std::vector<ul> prime;
  8. std::vector<bool> notprime(sp + 1, false);
  9. ul T;
  10. const ul maxn = 1e6;
  11. ull f[maxn + 1];
  12. ull remain[maxn + 1];
  13. ull l, r, k, p;
  14. int main()
  15. {
  16. for (ul i = 2; i <= sp; ++i) {
  17. if (!notprime[i]) {
  18. prime.push_back(i);
  19. }
  20. for (ul p : prime) {
  21. if (p * i > sp) {
  22. break;
  23. }
  24. notprime[p * i] = true;
  25. if (i % p == 0) {
  26. break;
  27. }
  28. }
  29. }
  30. std::scanf("%u", &T);
  31. for (ul Case = 1; Case <= T; ++Case) {
  32. std::scanf("%llu%llu%llu%llu", &l, &r, &k, &p);
  33. ull ans = 0;
  34. if (l == 0) {
  35. ++l;
  36. ans = (1 ^ k) % p;
  37. }
  38. for (ull i = l; i <= r; ++i) {
  39. f[i - l + 1] = 6;
  40. remain[i - l + 1] = i;
  41. }
  42. for (ull p : prime) {
  43. if (p * p > r) {
  44. break;
  45. }
  46. for (ull t = (l + p - 1) / p * p; t <= r; t += p) {
  47. ull tmp = 1;
  48. while (remain[t - l + 1] % p == 0) {
  49. remain[t - l + 1] /= p;
  50. tmp *= p;
  51. }
  52. if (p == 2) {
  53. continue;
  54. }
  55. if (p & 2) {
  56. f[t - l + 1] *= tmp + 2 * (tmp - 1) / (p - 1);
  57. } else {
  58. f[t - l + 1] *= tmp;
  59. }
  60. }
  61. }
  62. for (ull i = l; i <= r; ++i) {
  63. if (remain[i - l + 1] != 1) {
  64. if (remain[i - l + 1] == 2) {
  65. } else if (remain[i - l + 1] & 2) {
  66. f[i - l + 1] *= remain[i - l + 1] + 2;
  67. } else {
  68. f[i - l + 1] *= remain[i - l + 1];
  69. }
  70. }
  71. ans = (ans + (f[i - l + 1] ^ k)) % p;
  72. }
  73. std::printf("%llu\n", ans);
  74. }
  75. return 0;
  76. }

F、Paper Grading

分治

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. ul n, m;
  7. const ul maxn = 2e5;
  8. const ul maxm = 2e5;
  9. const ul maxlen = 2e5;
  10. char str[maxlen + 2];
  11. class node {
  12. public:
  13. ul ch[26];
  14. node() {
  15. std::memset(ch, 0, sizeof(ch));
  16. }
  17. };
  18. ul tot = 1;
  19. node tree[maxlen + 2];
  20. ul ptt[maxn + 1];
  21. ul dfn[maxlen + 2];
  22. ul bdfn[maxlen + 2];
  23. ul tim = 0;
  24. void search(ul curr) {
  25. ++tim;
  26. dfn[curr] = tim;
  27. for (ul i = 0; i != 26; ++i) {
  28. if (tree[curr].ch[i]) {
  29. search(tree[curr].ch[i]);
  30. }
  31. }
  32. bdfn[curr] = tim;
  33. }
  34. class data {
  35. public:
  36. bool insert = false;
  37. ul val = 0;
  38. ul time = 0;
  39. ul pos = 0;
  40. ul dfn = 0;
  41. };
  42. ul ans[maxm + 1];
  43. data v[maxn + maxm * 4 + 1];
  44. ul stack1[maxn + maxm * 4 + 1];
  45. ul stack2[maxn + maxm * 4 + 1];
  46. ul stack3[maxn + maxm * 4 + 1];
  47. void solve3(ul l, ul r)
  48. {
  49. if (v[stack3[l]].dfn == v[stack3[r]].dfn) {
  50. return;
  51. }
  52. ul tmp = 0;
  53. for (ul i = l, j = i; i <= r; i = j) {
  54. for (j = i; j <= r && v[stack3[j]].dfn == v[stack3[i]].dfn; ++j) {
  55. if (!v[stack3[j]].insert) {
  56. ans[v[stack3[j]].time] += v[stack3[j]].val * tmp;
  57. }
  58. }
  59. for (j = i; j <= r && v[stack3[j]].dfn == v[stack3[i]].dfn; ++j) {
  60. if (v[stack3[j]].insert) {
  61. tmp += v[stack3[j]].val;
  62. }
  63. }
  64. }
  65. }
  66. void solve2(ul l, ul r)
  67. {
  68. if (v[stack2[l]].pos == v[stack2[r]].pos) {
  69. return;
  70. }
  71. ul midl, midr;
  72. if ((l ^ r) & 1) {
  73. midl = l + r >> 1;
  74. midr = midl + 1;
  75. } else {
  76. midl = l + r >> 1;
  77. midr = midl;
  78. }
  79. ul s = v[stack2[midl]].pos;
  80. ul t = v[stack2[midr]].pos;
  81. if (s == t) {
  82. while (v[stack2[midl]].pos == s && v[stack2[midr]].pos == t) {
  83. --midl;
  84. ++midr;
  85. }
  86. if (v[stack2[midl]].pos != s) {
  87. midr = midl + 1;
  88. } else {
  89. midl = midr - 1;
  90. }
  91. }
  92. solve2(l, midl);
  93. solve2(midr, r);
  94. ul tot = 0;
  95. bool flag = false;
  96. for (ul i = l; i <= midl; ++i) {
  97. if (v[stack2[i]].insert) {
  98. ++tot;
  99. stack3[tot] = stack2[i];
  100. flag = true;
  101. }
  102. }
  103. if (!flag) {
  104. return;
  105. }
  106. flag = false;
  107. for (ul i = midr; i <= r; ++i) {
  108. if (!v[stack2[i]].insert) {
  109. ++tot;
  110. stack3[tot] = stack2[i];
  111. flag = true;
  112. }
  113. }
  114. if (!flag) {
  115. return;
  116. }
  117. std::sort(stack3 + 1, stack3 + tot + 1, [](ul a, ul b){return v[a].dfn < v[b].dfn;});
  118. solve3(1, tot);
  119. }
  120. void solve1(ul l, ul r)
  121. {
  122. if (v[stack1[l]].time == v[stack1[r]].time) {
  123. return;
  124. }
  125. ul midl, midr;
  126. if ((l ^ r) & 1) {
  127. midl = l + r >> 1;
  128. midr = midl + 1;
  129. } else {
  130. midl = l + r >> 1;
  131. midr = midl;
  132. }
  133. ul s = v[stack1[midl]].time;
  134. ul t = v[stack1[midr]].time;
  135. if (s == t) {
  136. while (v[stack1[midl]].time == s && v[stack1[midr]].time == t) {
  137. --midl;
  138. ++midr;
  139. }
  140. if (v[stack1[midl]].time != s) {
  141. midr = midl + 1;
  142. } else {
  143. midl = midr - 1;
  144. }
  145. }
  146. solve1(l, midl);
  147. solve1(midr, r);
  148. ul tot = 0;
  149. bool flag = false;
  150. for (ul i = l; i <= midl; ++i) {
  151. if (v[stack1[i]].insert) {
  152. ++tot;
  153. stack2[tot] = stack1[i];
  154. flag = true;
  155. }
  156. }
  157. if (!flag) {
  158. return;
  159. }
  160. flag = false;
  161. for (ul i = midr; i <= r; ++i) {
  162. if (!v[stack1[i]].insert) {
  163. ++tot;
  164. stack2[tot] = stack1[i];
  165. flag = true;
  166. }
  167. }
  168. if (!flag) {
  169. return;
  170. }
  171. std::sort(stack2 + 1, stack2 + tot + 1, [](ul a, ul b){return v[a].pos < v[b].pos;});
  172. solve2(1, tot);
  173. }
  174. bool isquery[maxm + 1];
  175. int main()
  176. {
  177. std::scanf("%u%u", &n, &m);
  178. for (ul i = 1; i <= n; ++i) {
  179. std::scanf("%s", str + 1);
  180. ul curr = 1;
  181. for (ul i = 1; str[i]; ++i) {
  182. if (!tree[curr].ch[str[i] - 'a']) {
  183. ++tot;
  184. tree[curr].ch[str[i] - 'a'] = tot;
  185. }
  186. curr = tree[curr].ch[str[i] - 'a'];
  187. }
  188. ptt[i] = curr;
  189. }
  190. search(1);
  191. tot = 0;
  192. for (ul i = 1; i <= n; ++i) {
  193. ++tot;
  194. v[tot].insert = true;
  195. v[tot].val = 1;
  196. v[tot].time = 0;
  197. v[tot].pos = i;
  198. v[tot].dfn = dfn[ptt[i]];
  199. };
  200. for (ul t = 1; t <= m; ++t) {
  201. ul opt;
  202. std::scanf("%u", &opt);
  203. if (opt == 1) {
  204. ul i, j;
  205. std::scanf("%u%u", &i, &j);
  206. if (i == j) {
  207. continue;
  208. }
  209. ++tot;
  210. v[tot].insert = true;
  211. v[tot].val = -1;
  212. v[tot].time = t;
  213. v[tot].pos = i;
  214. v[tot].dfn = dfn[ptt[i]];
  215. ++tot;
  216. v[tot].insert = true;
  217. v[tot].val = -1;
  218. v[tot].time = t;
  219. v[tot].pos = j;
  220. v[tot].dfn = dfn[ptt[j]];
  221. std::swap(ptt[i], ptt[j]);
  222. ++tot;
  223. v[tot].insert = true;
  224. v[tot].val = 1;
  225. v[tot].time = t;
  226. v[tot].pos = i;
  227. v[tot].dfn = dfn[ptt[i]];
  228. ++tot;
  229. v[tot].insert = true;
  230. v[tot].val = 1;
  231. v[tot].time = t;
  232. v[tot].pos = j;
  233. v[tot].dfn = dfn[ptt[j]];
  234. } else {
  235. isquery[t] = true;
  236. ul k, l, r;
  237. std::scanf("%s%u%u%u", str + 1, &k, &l, &r);
  238. ul len = std::strlen(str + 1);
  239. if (k > len) {
  240. continue;
  241. }
  242. ul curr = 1;
  243. bool flag = true;
  244. for (ul i = 1; i <= k; ++i) {
  245. if (!tree[curr].ch[str[i] - 'a']) {
  246. flag = false;
  247. break;
  248. }
  249. curr = tree[curr].ch[str[i] - 'a'];
  250. }
  251. if (!flag) {
  252. continue;
  253. }
  254. ++tot;
  255. v[tot].insert = false;
  256. v[tot].val = 1;
  257. v[tot].time = t;
  258. v[tot].pos = r + 1;
  259. v[tot].dfn = bdfn[curr] + 1;
  260. ++tot;
  261. v[tot].insert = false;
  262. v[tot].val = -1;
  263. v[tot].time = t;
  264. v[tot].pos = l;
  265. v[tot].dfn = bdfn[curr] + 1;
  266. ++tot;
  267. v[tot].insert = false;
  268. v[tot].val = -1;
  269. v[tot].time = t;
  270. v[tot].pos = r + 1;
  271. v[tot].dfn = dfn[curr];
  272. ++tot;
  273. v[tot].insert = false;
  274. v[tot].val = 1;
  275. v[tot].time = t;
  276. v[tot].pos = l;
  277. v[tot].dfn = dfn[curr];
  278. }
  279. }
  280. for (ul i = 1; i <= tot; ++i) {
  281. stack1[i] = i;
  282. }
  283. solve1(1, tot);
  284. for (ul i = 1; i <= m; ++i) {
  285. if (isquery[i]) {
  286. std::printf("%u\n", ans[i]);
  287. }
  288. }
  289. return 0;
  290. }

G、Poker Game

模拟。

  1. #pragma GCC target ("pclmul")
  2. #include <bits/stdc++.h>
  3. #include <emmintrin.h>
  4. #include <wmmintrin.h>
  5. using ul = std::uint32_t;
  6. using li = std::int32_t;
  7. using ull = std::uint64_t;
  8. using ll = std::int64_t;
  9. class card_t {
  10. public:
  11. ul suit = 0;
  12. ul number = 0;
  13. ul id = 0;
  14. card_t()=default;
  15. card_t(ul x): suit((x + 12) / 13), number((x - 1) % 13 + 1), id(x) {}
  16. };
  17. ul T;
  18. card_t deck[16];
  19. ul potcnt[6] = {0, 100, 100, 100, 100, 100};
  20. card_t holecards[6][3];
  21. card_t communitycards[6];
  22. ul state[6];
  23. std::pair<ul, ul> getvalue(card_t v[])
  24. {
  25. static std::pair<ul, ul> ret;
  26. if (v[1].suit == v[2].suit && v[1].suit == v[3].suit && v[1].suit == v[4].suit && v[1].suit == v[5].suit) {
  27. ret.first = 5;
  28. ret.second = v[5].number;
  29. if (v[1].number == 1) {
  30. ret.second = 14;
  31. }
  32. } else if (v[1].number + 1 == v[2].number && v[2].number + 1 == v[3].number && v[3].number + 1 == v[4].number && v[4].number + 1 == v[5].number || v[1].number == 1 && v[2].number == 10 && v[3].number == 11 && v[4].number == 12 && v[5].number == 13) {
  33. ret.first = 4;
  34. ret.second = v[5].number;
  35. if (v[1].number == 1 && v[5].number == 13) {
  36. ret.second = 14;
  37. }
  38. } else if (v[1].number == v[3].number || v[2].number == v[4].number || v[3].number == v[5].number) {
  39. ret.first = 3;
  40. for (ul i = 5; i >= 3; --i) {
  41. if (v[i].number == v[i - 2].number) {
  42. ret.second = v[i].number;
  43. break;
  44. }
  45. }
  46. if (v[1].number == v[3].number && v[1].number == 1) {
  47. ret.second = 14;
  48. }
  49. } else if (v[1].number == v[2].number || v[2].number == v[3].number || v[3].number == v[4].number || v[4].number == v[5].number) {
  50. ret.first = 2;
  51. for (ul i = 5; i >= 2; --i) {
  52. if (v[i].number == v[i - 1].number) {
  53. ret.second = v[i].number;
  54. break;
  55. }
  56. }
  57. if (v[1].number == v[2].number && v[1].number == 1) {
  58. ret.second = 14;
  59. }
  60. } else {
  61. ret.first = 1;
  62. ret.second = v[5].number;
  63. if (v[1].number == 1) {
  64. ret.second = 14;
  65. }
  66. }
  67. return ret;
  68. }
  69. std::vector<std::pair<ull, std::pair<ul, ul>>> map;
  70. std::vector<std::pair<ull, std::pair<ul, ul>>>::iterator find(ull x)
  71. {
  72. auto it = std::lower_bound(map.begin(), map.end(), std::pair<ull, std::pair<ul, ul>>(x, std::pair<ul, ul>(0, 0)));
  73. if (it == map.end() || it->first != x) {
  74. return map.end();
  75. } else {
  76. return it;
  77. }
  78. }
  79. const std::pair<ul, ul>& at(ull x)
  80. {
  81. return find(x)->second;
  82. }
  83. ull base;
  84. inline ull gfmul(ull a, ull b)
  85. {
  86. auto vc = _mm_clmulepi64_si128(_mm_cvtsi64_si128(a), _mm_cvtsi64_si128(b), 0);
  87. auto vf = _mm_xor_si128(_mm_cvtsi64_si128(_mm_cvtsi128_si64(vc)), _mm_clmulepi64_si128(_mm_srli_si128(vc, 8), _mm_cvtsi64_si128(27ull), 0));
  88. return _mm_cvtsi128_si64(_mm_xor_si128(_mm_cvtsi64_si128(_mm_cvtsi128_si64(vf)), _mm_clmulepi64_si128(_mm_srli_si128(vf, 8), _mm_cvtsi64_si128(27ull), 0)));
  89. }
  90. std::mt19937_64 rnd;
  91. card_t v1[6];
  92. card_t v2[6];
  93. ul v3[8];
  94. std::pair<ul, ul> ans[6];
  95. void getans(ul x)
  96. {
  97. for (ul i = 1; i <= 5; ++i) {
  98. v3[i] = communitycards[i].id;
  99. }
  100. for (ul i = 1; i <= 2; ++i) {
  101. v3[i + 5] = holecards[x][i].id;
  102. }
  103. ans[x] = std::pair<ul, ul>(0, 0);
  104. for (ul i = 1; i + 1 <= 7; ++i) {
  105. for (ul j = i + 1; j <= 7; ++j) {
  106. ull hash = 1;
  107. for (ul k = 1; k <= 7; ++k) {
  108. if (k != i && k != j) {
  109. hash = gfmul(hash, base ^ v3[k]);
  110. }
  111. }
  112. ans[x] = std::max(ans[x], at(hash));
  113. }
  114. }
  115. }
  116. ul ord[53];
  117. int main()
  118. {
  119. for (ul i = 1; i <= 52; ++i) {
  120. ord[i] = i;
  121. }
  122. std::sort(ord + 1, ord + 53, [](ul a, ul b){return (a - 1) % 13 < (b - 1) % 13;});
  123. rnd.seed(std::time(0));
  124. base = rnd();
  125. for (ul a1 = 1; a1 + 4 <= 52; ++a1) {
  126. ull hash1 = base ^ ord[a1];
  127. v1[1] = ord[a1];
  128. for (ul a2 = a1 + 1; a2 + 3 <= 52; ++a2) {
  129. ull hash2 = gfmul(hash1, base ^ ord[a2]);
  130. v1[2] = ord[a2];
  131. for (ul a3 = a2 + 1; a3 + 2 <= 52; ++a3) {
  132. ull hash3 = gfmul(hash2, base ^ ord[a3]);
  133. v1[3] = ord[a3];
  134. for (ul a4 = a3 + 1; a4 + 1 <= 52; ++a4) {
  135. ull hash4 = gfmul(hash3, base ^ ord[a4]);
  136. v1[4] = ord[a4];
  137. for (ul a5 = a4 + 1; a5 <= 52; ++a5) {
  138. ull hash5 = gfmul(hash4, base ^ ord[a5]);
  139. v1[5] = ord[a5];
  140. map.push_back(std::pair<ull, std::pair<ul, ul>>(hash5, getvalue(v1)));
  141. }
  142. }
  143. }
  144. }
  145. }
  146. std::sort(map.begin(), map.end());
  147. std::scanf("%u", &T);
  148. for (ul Case = 1; Case <= T; ++Case) {
  149. ul tot = 0;
  150. for (ul i = 1; i <= 15; ++i) {
  151. ul tmp;
  152. std::scanf("%u", &tmp);
  153. deck[i] = tmp;
  154. }
  155. ul alive = 0;
  156. ul last = 0;
  157. for (ul i = 1; i <= 5; ++i) {
  158. if (potcnt[i]) {
  159. ++alive;
  160. ++tot;
  161. holecards[i][1] = deck[tot];
  162. ++tot;
  163. holecards[i][2] = deck[tot];
  164. }
  165. }
  166. std::memset(state, 0, sizeof(state));
  167. if (potcnt[1] > 0) {
  168. if (potcnt[1] >= 15 && holecards[1][1].suit == holecards[1][2].suit) {
  169. state[1] = 1;
  170. } else {
  171. last = 1;
  172. --alive;
  173. }
  174. }
  175. if (potcnt[2] > 0) {
  176. if (potcnt[2] >= 15) {
  177. state[2] = 1;
  178. } else if (holecards[2][1].number == 1 && holecards[2][2].number == 1) {
  179. state[2] = 3;
  180. } else {
  181. last = 2;
  182. --alive;
  183. }
  184. }
  185. if (potcnt[3] > 0) {
  186. if (holecards[3][1].number == 1 || holecards[3][2].number == 1 || std::max(holecards[3][1].number, holecards[3][2].number) - std::min(holecards[3][1].number, holecards[3][2].number) < 3) {
  187. state[3] = 1 + ul(potcnt[3] < 15) * 2;
  188. } else {
  189. last = 3;
  190. --alive;
  191. }
  192. }
  193. if (potcnt[4] > 0) {
  194. if (holecards[4][1].number > 11 || holecards[4][1].number == 1 || holecards[4][2].number > 11 || holecards[4][2].number == 1) {
  195. state[4] = 1 + ul(potcnt[4] < 15) * 2;
  196. } else {
  197. last = 4;
  198. --alive;
  199. }
  200. }
  201. if (potcnt[5] > 0) {
  202. if (ul(state[1] != 0) + ul(state[2] != 0) + ul(state[3] != 0) + ul(state[4] != 0) == 1) {
  203. state[5] = 1 + ul(potcnt[5] < 15) * 2;
  204. } else {
  205. last = 5;
  206. --alive;
  207. }
  208. }
  209. for (ul i = 1; i <= 3; ++i) {
  210. ++tot;
  211. communitycards[i] = deck[tot];
  212. }
  213. if (state[1] == 1) {
  214. state[1] = 2;
  215. }
  216. if (state[2] == 1) {
  217. ull hashcurr = 1;
  218. for (ul i = 1; i <= 3; ++i) {
  219. hashcurr = gfmul(hashcurr, base ^ communitycards[i].id);
  220. v1[i] = communitycards[i];
  221. }
  222. for (ul i = 1; i <= 2; ++i) {
  223. hashcurr = gfmul(hashcurr, base ^ holecards[2][i].id);
  224. v1[i + 3] = holecards[2][i];
  225. }
  226. if (at(hashcurr).first >= 2) {
  227. state[2] = 2;
  228. } else {
  229. for (ul i = 1; i <= 5 && state[2] != 2; ++i) {
  230. ull hashcurr = 1;
  231. for (ul j = 1; j <= 5; ++j) {
  232. if (j != i) {
  233. hashcurr = gfmul(hashcurr, base ^ v1[j].id);
  234. }
  235. }
  236. for (ul t = 1; t <= 52; ++t) {
  237. ull hash = gfmul(hashcurr, base ^ t);
  238. auto it = find(hash);
  239. if (it != map.end() && it->second.first >= 4) {
  240. state[2] = 2;
  241. break;
  242. }
  243. }
  244. }
  245. }
  246. if (state[2] != 2) {
  247. --alive;
  248. last = 2;
  249. }
  250. }
  251. if (state[3] == 1) {
  252. bool flag = true;
  253. for (ul i = 1; i <= 3; ++i) {
  254. ul j = i + 1;
  255. if (j == 4) {
  256. j = 1;
  257. }
  258. if (communitycards[i].number == communitycards[j].number) {
  259. ul t = communitycards[i].number;
  260. bool flag2 = false;
  261. for (ul i = 1; i <= 2; ++i) {
  262. if (holecards[3][i].number == t) {
  263. flag2 = true;
  264. break;
  265. }
  266. }
  267. if (!flag2) {
  268. flag = false;
  269. break;
  270. }
  271. }
  272. }
  273. if (flag) {
  274. state[3] = 2;
  275. } else {
  276. --alive;
  277. last = 3;
  278. }
  279. }
  280. if (state[4] == 1) {
  281. ul maxcom = 0;
  282. for (ul i = 1; i <= 3; ++i) {
  283. if (communitycards[i].number == 1) {
  284. maxcom = 14;
  285. break;
  286. }
  287. maxcom = std::max(maxcom, communitycards[i].number);
  288. }
  289. ul maxhole = 0;
  290. for (ul i = 1; i <= 2; ++i) {
  291. if (holecards[4][i].number == 1) {
  292. maxhole = 14;
  293. break;
  294. }
  295. maxhole = std::max(maxhole, holecards[4][i].number);
  296. }
  297. if (maxhole >= maxcom) {
  298. state[4] = 2;
  299. } else {
  300. --alive;
  301. last = 4;
  302. }
  303. }
  304. if (state[5] == 1) {
  305. state[5] = 2;
  306. }
  307. for (ul i = 4; i <= 5; ++i) {
  308. ++tot;
  309. communitycards[i] = deck[tot];
  310. }
  311. if (state[1] == 2) {
  312. getans(1);
  313. if (ans[1].first >= 2) {
  314. state[1] = 3;
  315. } else {
  316. --alive;
  317. last = 1;
  318. }
  319. }
  320. if (state[2] == 2) {
  321. bool flag = false;
  322. for (ul i = 1; i <= 5; ++i) {
  323. ul t = communitycards[1].suit;
  324. if (i == 1) {
  325. t = communitycards[2].suit;
  326. }
  327. bool flag2 = true;
  328. for (ul j = 1; j <= 5; ++j) {
  329. if (j == i) {
  330. continue;
  331. }
  332. if (communitycards[j].suit != t) {
  333. flag2 = false;
  334. break;
  335. }
  336. }
  337. if (flag2) {
  338. flag = true;
  339. break;
  340. }
  341. }
  342. if (!flag) {
  343. state[2] = 3;
  344. } else {
  345. --alive;
  346. last = 2;
  347. }
  348. }
  349. if (state[3] == 2) {
  350. state[3] = 3;
  351. }
  352. if (state[4] == 2) {
  353. getans(4);
  354. if (ans[4].first >= 3) {
  355. state[4] = 3;
  356. } else if (ans[4].first >= 2) {
  357. std::sort(communitycards + 1, communitycards + 6, [](const card_t& a, const card_t& b){return (a.number == 1) != (b.number == 1) ? b.number == 1 : a.number < b.number;});
  358. if (ans[4].second > communitycards[3].number && communitycards[3].number != 1) {
  359. state[4] = 3;
  360. }
  361. }
  362. if (state[4] != 3) {
  363. --alive;
  364. last = 4;
  365. }
  366. }
  367. if (state[5] == 2) {
  368. state[5] = 3;
  369. }
  370. std::pair<ul, ul> winval(0, 0);
  371. ul winner = 0;
  372. if (alive == 0) {
  373. winner = last;
  374. }
  375. for (ul i = 1; i <= 5; ++i) {
  376. if (state[i] == 3) {
  377. getans(i);
  378. if (winval <= ans[i]) {
  379. winval = ans[i];
  380. winner = i;
  381. }
  382. }
  383. }
  384. if (winner) {
  385. ul sum = 0;
  386. for (ul i = 1; i <= 5; ++i) {
  387. if (i != winner) {
  388. sum += std::min(potcnt[i], 5 * state[i]);
  389. potcnt[i] -= std::min(potcnt[i], 5 * state[i]);
  390. }
  391. }
  392. potcnt[winner] += sum;
  393. }
  394. }
  395. for (ul i = 1; i <= 5; ++i) {
  396. std::printf("%u\n", potcnt[i]);
  397. }
  398. return 0;
  399. }

H、Prince and Princess

我一直没搞懂这种题要严格证明最优性该从哪里入手。
策略是:如果只有公主一人,什么都不用问,如果支持者多于其他人,则挨着一直问公主在哪,问次,一定有一个答案出现了至少次,就是答案。

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. ul a, b, c;
  7. int main()
  8. {
  9. std::scanf("%u%u%u", &a, &b, &c);
  10. if (a == 1 && b == 0 && c == 0) {
  11. std::printf("YES\n0\n");
  12. } else if (a <= b + c) {
  13. std::printf("NO\n");
  14. } else {
  15. std::printf("YES\n%u\n", (b + c << 1) + 1);
  16. }
  17. return 0;
  18. }

I、Space Station

注意和属于的不降正整数列一共只有个,于是可以记忆化搜索。用的是来哈希,用会撞哈希。

  1. #pragma GCC target ("pclmul")
  2. #include <bits/stdc++.h>
  3. #include <emmintrin.h>
  4. #include <wmmintrin.h>
  5. using ul = std::uint32_t;
  6. using li = std::int32_t;
  7. using ull = std::uint64_t;
  8. using ll = std::int64_t;
  9. const ul mod = 1e9 + 7;
  10. ul plus(ul a, ul b)
  11. {
  12. return a + b < mod ? a + b : a + b - mod;
  13. }
  14. ul mul(ul a, ul b)
  15. {
  16. return ull(a) * ull(b) % mod;
  17. }
  18. void exgcd(li a, li b, li& x, li& y)
  19. {
  20. if (b) {
  21. exgcd(b, a % b, y, x);
  22. y -= a / b * x;
  23. } else {
  24. x = 1;
  25. y = 0;
  26. }
  27. }
  28. ul inverse(ul a)
  29. {
  30. li x, y;
  31. exgcd(a, mod, x, y);
  32. return x < 0 ? x + li(mod) : x;
  33. }
  34. inline ull gfmul(ull a, ull b)
  35. {
  36. auto vc = _mm_clmulepi64_si128(_mm_cvtsi64_si128(a), _mm_cvtsi64_si128(b), 0);
  37. auto vf = _mm_xor_si128(_mm_cvtsi64_si128(_mm_cvtsi128_si64(vc)), _mm_clmulepi64_si128(_mm_srli_si128(vc, 8), _mm_cvtsi64_si128(27ull), 0));
  38. return _mm_cvtsi128_si64(_mm_xor_si128(_mm_cvtsi64_si128(_mm_cvtsi128_si64(vf)), _mm_clmulepi64_si128(_mm_srli_si128(vf, 8), _mm_cvtsi64_si128(27ull), 0)));
  39. }
  40. ul n;
  41. ul cnt[51];
  42. std::unordered_map<ull, ul> ans;
  43. ull base;
  44. const ul maxn = 1e5;
  45. ul fac[maxn + 1];
  46. ul fiv[maxn + 1];
  47. ull hash = 1;
  48. ul sum;
  49. ul remain;
  50. ul search()
  51. {
  52. if (sum >= 50 || !remain) {
  53. return fac[remain];
  54. }
  55. auto it = ans.find(hash);
  56. if (it != ans.end()) {
  57. return it->second;
  58. }
  59. ul tmp = 0;
  60. for (ul i = 1; i <= sum; ++i) {
  61. if (!cnt[i]) {
  62. continue;
  63. }
  64. --cnt[i];
  65. sum += i;
  66. --remain;
  67. ull chash = hash;
  68. hash = gfmul(hash, base ^ i);
  69. ul t = search();
  70. ++cnt[i];
  71. sum -= i;
  72. ++remain;
  73. hash = chash;
  74. tmp = plus(tmp, mul(cnt[i], t));
  75. }
  76. ans[hash] = tmp;
  77. return tmp;
  78. }
  79. std::mt19937_64 rnd;
  80. int main()
  81. {
  82. rnd.seed(std::time(0));
  83. base = rnd();
  84. fac[0] = 1;
  85. for (ul i = 1; i <= maxn; ++i) {
  86. fac[i] = mul(fac[i - 1], i);
  87. }
  88. fiv[maxn] = inverse(fac[maxn]);
  89. for (ul i = maxn; i >= 1; --i) {
  90. fiv[i - 1] = mul(fiv[i], i);
  91. }
  92. std::scanf("%u", &n);
  93. std::scanf("%u", &sum);
  94. for (ul i = 1; i <= n; ++i) {
  95. ul a;
  96. std::scanf("%u", &a);
  97. ++cnt[a];
  98. if (a) {
  99. ++remain;
  100. }
  101. }
  102. ul tmp = search();
  103. std::printf("%u\n", mul(tmp, mul(fac[n], fiv[remain])));
  104. return 0;
  105. }

J、Spy

关于最小权匹配的算法:https://www.zybuluo.com/qq290637843/note/1774018

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using pllul = std::pair<ll, ul>;
  7. ul n;
  8. const ul maxn = 400;
  9. ll a[maxn + 1];
  10. ul p[maxn + 1];
  11. ll b[maxn + 1];
  12. ll c[maxn + 1];
  13. ul ord[maxn + 1];
  14. std::vector<pllul> sum;
  15. const ll inf = ll(2e18) + 1;
  16. ll w[maxn + 1][maxn + 1];
  17. ul x[maxn + 1];
  18. ul y[maxn + 1];
  19. void lapjv(ul n, const ll c[][maxn + 1], ul x[maxn + 1], ul y[maxn + 1])
  20. {
  21. static ll u[maxn + 1];
  22. static ll v[maxn + 1];
  23. static ll d[maxn + 1];
  24. static ul pred[maxn + 1];
  25. static bool vis[maxn + 1];
  26. std::memset(u + 1, 0, sizeof(ll) * n);
  27. std::memset(x + 1, 0, sizeof(ul) * n);
  28. std::memset(y + 1, 0, sizeof(ul) * n);
  29. for (ul j = 1; j <= n; ++j) {
  30. v[j] = 0;
  31. for (ul i = 1; i <= n; ++i) {
  32. v[j] = std::min(v[j], c[i][j]);
  33. }
  34. }
  35. for (ul istar = 1; istar <= n; ++istar) {
  36. for (ul j = 1; j <= n; ++j) {
  37. d[j] = c[istar][j] - u[istar] - v[j];
  38. pred[j] = istar;
  39. vis[j] = false;
  40. }
  41. ul endj;
  42. ll mu;
  43. while (true) {
  44. ul jstar;
  45. mu = inf;
  46. for (ul j = 1; j <= n; ++j) {
  47. if (!vis[j] && mu > d[j]) {
  48. jstar = j;
  49. mu = d[j];
  50. }
  51. }
  52. if (!y[jstar]) {
  53. endj = jstar;
  54. break;
  55. }
  56. vis[jstar] = true;
  57. ul i = y[jstar];
  58. for (ul j = 1; j <= n; ++j) {
  59. if (mu + c[i][j] - u[i] - v[j] < d[j]) {
  60. d[j] = mu + c[i][j] - u[i] - v[j];
  61. pred[j] = i;
  62. }
  63. }
  64. }
  65. for (ul k = 1; k <= n; ++k) {
  66. if (d[k] < mu) {
  67. v[k] -= mu - d[k];
  68. }
  69. }
  70. ul j = endj;
  71. while (true) {
  72. ul i = pred[j];
  73. y[j] = i;
  74. std::swap(j, x[i]);
  75. if (i == istar) {
  76. break;
  77. }
  78. }
  79. for (ul i = 1; i <= istar; ++i) {
  80. u[i] = c[i][x[i]] - v[x[i]];
  81. }
  82. }
  83. }
  84. int main()
  85. {
  86. std::scanf("%u", &n);
  87. for (ul i = 1; i <= n; ++i) {
  88. std::scanf("%lld", &a[i]);
  89. ord[i] = i;
  90. }
  91. for (ul i = 1; i <= n; ++i) {
  92. std::scanf("%lld", &p[i]);
  93. }
  94. std::sort(ord + 1, ord + n + 1, [](ul x, ul y){return a[x] < a[y];});
  95. sum.push_back(pllul(-inf, 0));
  96. for (ul i = 1; i <= n; ++i) {
  97. if (a[ord[i]] != sum.back().first) {
  98. sum.push_back(pllul(a[ord[i]], sum.back().second));
  99. }
  100. sum.back().second += p[ord[i]];
  101. }
  102. for (ul i = 1; i <= n; ++i) {
  103. std::scanf("%lld", &b[i]);
  104. }
  105. for (ul i = 1; i <= n; ++i) {
  106. std::scanf("%lld", &c[i]);
  107. }
  108. for (ul i = 1; i <= n; ++i) {
  109. for (ul j = 1; j <= n; ++j) {
  110. w[i][j] = -ll(std::prev(std::lower_bound(sum.begin(), sum.end(), pllul(b[i] + c[j], 0)))->second);
  111. }
  112. }
  113. lapjv(n, w, x, y);
  114. ll ans = 0;
  115. for (ul i = 1; i <= n; ++i) {
  116. ans -= w[i][x[i]];
  117. }
  118. std::printf("%lld\n", ans);
  119. return 0;
  120. }

K、Triangle

简单题

  1. #include <bits/stdc++.h>
  2. using ul = std::uint32_t;
  3. using li = std::int32_t;
  4. using ull = std::uint64_t;
  5. using ll = std::int64_t;
  6. using lf = double;
  7. class vec {
  8. public:
  9. lf x = 0;
  10. lf y = 0;
  11. vec()=default;
  12. vec(lf x, lf y): x(x), y(y) {}
  13. };
  14. vec operator+(const vec& a, const vec& b)
  15. {
  16. return vec(a.x + b.x, a.y + b.y);
  17. }
  18. vec operator-(const vec& a, const vec& b)
  19. {
  20. return vec(a.x - b.x, a.y - b.y);
  21. }
  22. lf operator*(const vec& a, const vec& b)
  23. {
  24. return a.x * b.x + a.y * b.y;
  25. }
  26. lf operator^(const vec& a, const vec& b)
  27. {
  28. return a.x * b.y - a.y * b.x;
  29. }
  30. vec operator*(lf a, const vec& b)
  31. {
  32. return vec(a * b.x, a * b.y);
  33. }
  34. ul T;
  35. vec a, b, c, p, q;
  36. int main()
  37. {
  38. std::scanf("%u", &T);
  39. for (ul Case = 1; Case <= T; ++Case) {
  40. std::scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &a.x, &a.y, &b.x, &b.y, &c.x, &c.y, &p.x, &p.y);
  41. if (!(a - p ^ b - p) && (a - p) * (b - p) <= 0) {
  42. } else if (!(a - p ^ c - p) && (a - p) * (b - p) <= 0) {
  43. std::swap(b, c);
  44. } else if (!(b - p ^ c - p) && (b - p) * (c - p) <= 0) {
  45. std::swap(a, b);
  46. } else {
  47. std::printf("-1\n");
  48. continue;
  49. }
  50. if ((a - c ^ b - c) < 0) {
  51. std::swap(a, b);
  52. }
  53. lf s = a - c ^ p - c;
  54. lf t = p - c ^ b - c;
  55. if (s == t) {
  56. q = c;
  57. } else if (s < t) {
  58. q = lf(0.5) * (s + t) / (c - b ^ p - b) * (c - b) + b;
  59. } else {
  60. q = lf(0.5) * (s + t) / (p - a ^ c - a) * (c - a) + a;
  61. }
  62. std::printf("%.20lf %.20lf\n", q.x, q.y);
  63. }
  64. return 0;
  65. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注