[关闭]
@qq290637843 2020-12-06T01:38:46.000000Z 字数 20827 阅读 239

2020杭电第四场

A、Anti-AK Problem 6802

首先,将球单位化。
采用球极投影(注意,球极投影之后,圆可能变成圆,也可能变成直线,为了避免出现特殊情况,将在一开始随机换一个新的正交标架),来给球面上的点赋予新的坐标:

于是可知第一基本形式为
于是面积微元为
其为如下微分形式的外微分:
于是任何一个参数曲线(可能是反向的)所提供的贡献为
此积分作为不定积分等于:
注意不要直接就代值用减法,要把那些跳跃点挖掉。

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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. using lf = double;
  10. using llf = long double;
  11. using dt = llf;
  12. std::mt19937 gen;
  13. std::normal_distribution<dt> d(dt(0), dt(1) / std::sqrt(dt(3)));
  14. dt mat[4][4];
  15. dt fromv[4];
  16. dt tov[4];
  17. ul T;
  18. ul n;
  19. dt R;
  20. dt r0;
  21. const dt pi = std::acos(dt(-1));
  22. const ul maxn = 5e3;
  23. class circ {
  24. public:
  25. dt x = 0;
  26. dt y = 0;
  27. dt r = 0;
  28. bool clock = false;
  29. };
  30. circ cs[maxn + 1];
  31. dt sqr(dt a)
  32. {
  33. return a * a;
  34. }
  35. dt dir(dt x, dt y)
  36. {
  37. return x > 0 ? (y >= 0 ? std::atan(y / x) : pi + pi + std::atan(y / x)) : (x < 0 ? pi + std::atan(y / x) : (y > 0 ? pi * dt(0.5) : pi * dt(1.5)));
  38. }
  39. dt tracos(dt a2, dt b2, dt c2)
  40. {
  41. return std::acos(std::min(dt(1), std::max(dt(-1), (b2 + c2 - a2) / std::sqrt(4.0 * b2 * c2))));
  42. }
  43. std::vector<std::pair<dt, char>> stack;
  44. void push(std::vector<std::pair<dt, char>>& v, dt alpha, dt beta)
  45. {
  46. if (alpha <= beta) {
  47. while (beta > pi + pi) {
  48. alpha -= pi + pi;
  49. beta -= pi + pi;
  50. }
  51. if (alpha >= dt(0)) {
  52. v.push_back(std::pair<dt, char>(alpha, '('));
  53. v.push_back(std::pair<dt, char>(beta, ')'));
  54. } else {
  55. v.push_back(std::pair<dt, char>(alpha + pi + pi, '('));
  56. v.push_back(std::pair<dt, char>(pi + pi, ')'));
  57. v.push_back(std::pair<dt, char>(dt(0), '('));
  58. v.push_back(std::pair<dt, char>(beta, ')'));
  59. }
  60. } else {
  61. while (alpha > pi + pi) {
  62. alpha -= pi + pi;
  63. beta -= pi + pi;
  64. }
  65. if (beta >= dt(0)) {
  66. v.push_back(std::pair<dt, char>(alpha, '('));
  67. v.push_back(std::pair<dt, char>(beta, ')'));
  68. } else {
  69. v.push_back(std::pair<dt, char>(alpha, '('));
  70. v.push_back(std::pair<dt, char>(dt(0), ')'));
  71. v.push_back(std::pair<dt, char>(pi + pi, '('));
  72. v.push_back(std::pair<dt, char>(beta + pi + pi, ')'));
  73. }
  74. }
  75. }
  76. dt f(dt t, dt x0, dt y0, dt r)
  77. {
  78. dt sqrt2 = std::sqrt(dt(2));
  79. dt sint = std::sin(t);
  80. dt cost = std::cos(t);
  81. dt r2 = r * r;
  82. dt x2py2 = x0 * x0 + y0 * y0;
  83. dt A = std::sqrt(r2 * r2 - 2 * r2 * (-4 + x2py2) + sqr(4 + x2py2));
  84. dt B = std::sqrt(8 + 2 * sqr(r * sint + y0));
  85. return t + 2 * (-4 + r2 - x2py2) * (std::atan((2 * r * y0 + (4 + r2 - 2 * r * x0 + x2py2) * std::tan(t / 2)) / A) + (t > pi ? pi : dt(0))) / A + 2 * sqrt2 * std::atan(sqrt2 * (x0 + r * cost) / B) * (y0 + r * sint) / B;
  86. }
  87. dt getans(dt x0, dt y0, dt r, dt a, dt b)
  88. {
  89. if (a == b) {
  90. return 0;
  91. }
  92. return f(b, x0, y0, r) - f(a, x0, y0, r);
  93. }
  94. dt in()
  95. {
  96. lf tmp;
  97. iss >> tmp;
  98. return tmp;
  99. }
  100. int main()
  101. {
  102. std::ios::sync_with_stdio(false);
  103. std::cin.tie(0);
  104. iss.tie(0);
  105. oss.tie(0);
  106. std::getline(std::cin, instr, char(0));
  107. iss.str(instr);
  108. gen.seed(std::time(0));
  109. iss >> T;
  110. for (ul Case = 1; Case <= T; ++Case) {
  111. for (ul i = 1; i <= 3; ++i) {
  112. for (ul j = 1; j <= 3; ++j) {
  113. mat[i][j] = d(gen);
  114. }
  115. for (ul j = 1; j < i; ++j) {
  116. dt s = 0;
  117. for (ul k = 1; k <= 3; ++k) {
  118. s += mat[i][k] * mat[j][k];
  119. }
  120. for (ul k = 1; k <= 3; ++k) {
  121. mat[i][k] -= mat[j][k] * s;
  122. }
  123. }
  124. dt s = 0;
  125. for (ul j = 1; j <= 3; ++j) {
  126. s += mat[i][j] * mat[i][j];
  127. }
  128. s = std::sqrt(s);
  129. for (ul j = 1; j <= 3; ++j) {
  130. mat[i][j] /= s;
  131. }
  132. }
  133. iss >> n;
  134. R = in();
  135. r0 = in();
  136. r0 /= R;
  137. for (ul i = 1; i <= n; ++i) {
  138. dt x, y, z, r;
  139. fromv[1] = in();
  140. fromv[2] = in();
  141. fromv[3] = in();
  142. r = in();
  143. for (ul i = 1; i <= 3; ++i) {
  144. tov[i] = 0;
  145. for (ul j = 1; j <= 3; ++j) {
  146. tov[i] += fromv[j] * mat[j][i];
  147. }
  148. }
  149. x = tov[1] / R;
  150. y = tov[2] / R;
  151. z = tov[3] / R;
  152. r /= R;
  153. x *= dt(2) / (dt(1) - z);
  154. y *= dt(2) / (dt(1) - z);
  155. dt rxy = std::sqrt(x * x + y * y);
  156. dt dis1 = dt(2) * std::atan(rxy * dt(0.5));
  157. dt dis2 = dis1 - r;
  158. dt dis3 = dis1 + r;
  159. if (dis3 > pi) {
  160. cs[i].clock = true;
  161. dis3 -= pi + pi;
  162. dis2 = dt(2) * std::tan(dis2 * dt(0.5));
  163. dis3 = dt(2) * std::tan(dis3 * dt(0.5));
  164. dis1 = (dis2 + dis3) * dt(0.5);
  165. cs[i].x = x * dis1 / rxy;
  166. cs[i].y = y * dis1 / rxy;
  167. cs[i].r = (dis2 - dis3) * dt(0.5);
  168. } else {
  169. cs[i].clock = false;
  170. dis2 = dt(2) * std::tan(dis2 * dt(0.5));
  171. dis3 = dt(2) * std::tan(dis3 * dt(0.5));
  172. dis1 = (dis2 + dis3) * dt(0.5);
  173. cs[i].x = x * dis1 / rxy;
  174. cs[i].y = y * dis1 / rxy;
  175. cs[i].r = (dis3 - dis2) * dt(0.5);
  176. }
  177. }
  178. dt ans = 0;
  179. bool flag = false;
  180. for (ul i = 1; i <= n; ++i) {
  181. if (cs[i].clock) {
  182. flag = true;
  183. }
  184. stack.resize(0);
  185. for (ul j = 1; j <= n; ++j) {
  186. if (i == j) {
  187. continue;
  188. }
  189. if (cs[i].x == cs[j].x && cs[i].y == cs[j].y && cs[i].r == cs[j].r) {
  190. if (i > j && !cs[i].clock) {
  191. push(stack, dt(0), pi + pi);
  192. break;
  193. }
  194. if (i > j && cs[i].clock) {
  195. push(stack, pi + pi, dt(0));
  196. break;
  197. }
  198. continue;
  199. }
  200. if (sqr(cs[i].x - cs[j].x) + sqr(cs[i].y - cs[j].y) >= sqr(cs[i].r + cs[j].r)) {
  201. if (!cs[i].clock && cs[j].clock) {
  202. push(stack, dt(0), pi + pi);
  203. break;
  204. }
  205. continue;
  206. }
  207. if (sqr(cs[i].x - cs[j].x) + sqr(cs[i].y - cs[j].y) <= sqr(cs[i].r - cs[j].r)) {
  208. if (cs[i].r <= cs[j].r && !cs[i].clock && !cs[j].clock) {
  209. push(stack, dt(0), pi + pi);
  210. break;
  211. }
  212. if (cs[i].r >= cs[j].r && cs[i].clock && cs[j].clock) {
  213. push(stack, pi + pi, dt(0));
  214. break;
  215. }
  216. continue;
  217. }
  218. dt gamma = dir(cs[j].x - cs[i].x, cs[j].y - cs[i].y);
  219. dt theta = tracos(sqr(cs[j].r), sqr(cs[i].r), sqr(cs[i].x - cs[j].x) + sqr(cs[i].y - cs[j].y));
  220. dt alpha = gamma - theta;
  221. dt beta = gamma + theta;
  222. if (!cs[i].clock) {
  223. if (!cs[j].clock) {
  224. push(stack, alpha, beta);
  225. } else {
  226. push(stack, beta, alpha + pi + pi);
  227. }
  228. } else {
  229. if (!cs[j].clock) {
  230. push(stack, beta, alpha);
  231. } else {
  232. push(stack, alpha + pi + pi, beta);
  233. }
  234. }
  235. }
  236. if (!cs[i].clock) {
  237. std::sort(stack.begin(), stack.end(), [](const std::pair<dt, char>& a, const std::pair<dt, char>& b){return a.first != b.first ? a.first < b.first : a.second < b.second;});
  238. } else {
  239. std::sort(stack.begin(), stack.end(), [](const std::pair<dt, char>& a, const std::pair<dt, char>& b){return a.first != b.first ? a.first > b.first : a.second < b.second;});
  240. }
  241. ul cnt = 0;
  242. dt prev;
  243. if (!cs[i].clock) {
  244. prev = 0;
  245. } else {
  246. prev = pi + pi;
  247. }
  248. for (const auto &p : stack) {
  249. if (cnt == 0) {
  250. ans += getans(cs[i].x, cs[i].y, cs[i].r, prev, p.first);
  251. }
  252. if (p.second == '(') {
  253. ++cnt;
  254. } else {
  255. --cnt;
  256. }
  257. if (cnt == 0) {
  258. prev = p.first;
  259. }
  260. }
  261. if (!cs[i].clock) {
  262. ans += getans(cs[i].x, cs[i].y, cs[i].r, prev, pi + pi);
  263. } else {
  264. ans += getans(cs[i].x, cs[i].y, cs[i].r, prev, 0);
  265. }
  266. }
  267. if (flag) {
  268. ans += pi + pi + pi + pi;
  269. }
  270. ans = ans + (pi + pi + pi + pi - ans) * getans(0, 0, dt(2) * std::tan(r0 * dt(0.5)), 0, pi + pi) / (pi + pi + pi + pi);
  271. oss << std::fixed << std::setprecision(20) << lf(ans * R * R) << '\n';
  272. }
  273. std::cout << oss.str();
  274. return 0;
  275. }

B、Blow up the Enemy 6803

简单题

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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. using lf = double;
  10. ul T, n;
  11. int main()
  12. {
  13. std::ios::sync_with_stdio(false);
  14. std::cin.tie(0);
  15. iss.tie(0);
  16. oss.tie(0);
  17. std::freopen("B.in", "r", stdin);
  18. std::getline(std::cin, instr, char(0));
  19. iss.str(instr);
  20. iss >> T;
  21. for (ul Case = 1; Case <= T; ++Case) {
  22. iss >> n;
  23. ul mn = 1e9;
  24. ul cnt = 0;
  25. for (ul i = 1; i <= n; ++i) {
  26. ul a, d;
  27. iss >> a >> d;
  28. ul v = ((100 + a - 1) / a - 1) * d;
  29. if (mn > v) {
  30. mn = v;
  31. cnt = 0;
  32. }
  33. if (mn == v) {
  34. ++cnt;
  35. }
  36. }
  37. oss << std::fixed << std::setprecision(20) << lf(n + n - cnt) / lf(n << 1) << '\n';
  38. }
  39. std::freopen("out.txt", "w", stdout);
  40. std::cout << oss.str();
  41. return 0;
  42. }

C、Contest of Rope Pulling 6804

官方题解如下:
新建位图图像.png-223.4kB

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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. using plili = std::pair<li, li>;
  10. using lf = double;
  11. std::mt19937_64 rnd;
  12. const ul maxn = 1e3;
  13. const ul maxm = 1e3;
  14. const ul maxa = 1000 * std::sqrt(std::acos(lf(-1)) * (maxn + maxm)) + 1;
  15. ul a;
  16. ul n, m;
  17. plili v[maxn + maxm + 1];
  18. ll ans[maxa + maxa + 1];
  19. ul T;
  20. int main()
  21. {
  22. std::ios::sync_with_stdio(false);
  23. std::cin.tie(0);
  24. iss.tie(0);
  25. oss.tie(0);
  26. std::getline(std::cin, instr, char(0));
  27. iss.str(instr);
  28. rnd.seed(std::time(0));
  29. iss >> T;
  30. for (ul Case = 1; Case <= T; ++Case) {
  31. iss >> n >> m;
  32. a = 1000 * std::sqrt(std::acos(lf(-1)) * (n + m)) + 1;
  33. for (ul i = 1; i <= n; ++i) {
  34. iss >> v[i].first >> v[i].second;
  35. }
  36. for (ul i = n + 1; i <= n + m; ++i) {
  37. iss >> v[i].first >> v[i].second;
  38. v[i].first = -v[i].first;
  39. }
  40. for (ul i = n + m; i >= 1; --i) {
  41. std::swap(v[i], v[rnd() % i + 1]);
  42. }
  43. for (ul i = 0; i <= a + a; ++i) {
  44. ans[i] = -1e15;
  45. }
  46. ans[a] = 0;
  47. for (ul i = 1; i <= n + m; ++i) {
  48. if (v[i].first > 0) {
  49. for (ul j = a + a; j >= v[i].first; --j) {
  50. ans[j] = std::max(ans[j], ans[j - v[i].first] + v[i].second);
  51. }
  52. } else {
  53. for (ul j = 0; j <= a + a + v[i].first; ++j) {
  54. ans[j] = std::max(ans[j], ans[j - v[i].first] + v[i].second);
  55. }
  56. }
  57. }
  58. oss << ans[a] << '\n';
  59. }
  60. std::cout << oss.str();
  61. return 0;
  62. }

D、Deliver the Cake 6805

简单题

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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 maxn = 1e5;
  10. ul T;
  11. ul n, m, s, t, x;
  12. class edge_t {
  13. public:
  14. ul to = 0;
  15. ull len = 0;
  16. edge_t()=default;
  17. edge_t(ul a, ull b): to(a), len(b) {}
  18. };
  19. bool operator<(const edge_t& a, const edge_t& b)
  20. {
  21. return a.len > b.len;
  22. }
  23. char type[maxn + 2];
  24. std::vector<edge_t> edge[maxn + maxn + 2 + 1];
  25. void connect2(ul a, ul b, ul d)
  26. {
  27. edge[a].push_back(edge_t(b, d));
  28. edge[b].push_back(edge_t(a, d));
  29. }
  30. void connect(ul a, ul b, ul d)
  31. {
  32. if (type[a] != 'R') {
  33. if (type[b] != 'R') {
  34. connect2(a, b, d);
  35. }
  36. if (type[b] != 'L') {
  37. connect2(a, b + n, d + x);
  38. }
  39. }
  40. if (type[a] != 'L') {
  41. if (type[b] != 'R') {
  42. connect2(a + n, b, d + x);
  43. }
  44. if (type[b] != 'L') {
  45. connect2(a + n, b + n, d);
  46. }
  47. }
  48. }
  49. std::priority_queue<edge_t> heap;
  50. ull dis[maxn + maxn + 2 + 1];
  51. int main()
  52. {
  53. std::ios::sync_with_stdio(false);
  54. std::cin.tie(0);
  55. iss.tie(0);
  56. oss.tie(0);
  57. std::getline(std::cin, instr, char(0));
  58. iss.str(instr);
  59. iss >> T;
  60. for (ul Case = 1; Case <= T; ++Case) {
  61. iss >> n >> m >> s >> t >> x >> type + 1;
  62. for (ul i = 1; i <= n + n + 2; ++i) {
  63. edge[i].resize(0);
  64. dis[i] = 1e18;
  65. }
  66. if (type[s] != 'R') {
  67. connect2(n + n + 1, s, 0);
  68. }
  69. if (type[s] != 'L') {
  70. connect2(n + n + 1, s + n, 0);
  71. }
  72. if (type[t] != 'R') {
  73. connect2(n + n + 2, t, 0);
  74. }
  75. if (type[t] != 'L') {
  76. connect2(n + n + 2, t + n, 0);
  77. }
  78. for (ul i = 1; i <= m; ++i) {
  79. ul a, b, d;
  80. iss >> a >> b >> d;
  81. connect(a, b, d);
  82. }
  83. while (heap.size()) {
  84. heap.pop();
  85. }
  86. heap.push(edge_t(n + n + 1, 0));
  87. dis[n + n + 1] = 0;
  88. while (true) {
  89. auto curr = heap.top();
  90. if (curr.to == n + n + 2) {
  91. oss << curr.len << '\n';
  92. break;
  93. }
  94. heap.pop();
  95. if (curr.len > dis[curr.to]) {
  96. continue;
  97. }
  98. for (const auto& next : edge[curr.to]) {
  99. if (next.len + curr.len < dis[next.to]) {
  100. dis[next.to] = next.len + curr.len;
  101. heap.push(edge_t(next.to, next.len + curr.len));
  102. }
  103. }
  104. }
  105. }
  106. std::cout << oss.str();
  107. return 0;
  108. }

E、Equal Sentences 6806

表示长为的前缀所对应的答案,递推式很容易想到。

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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. std::string curr, next;
  10. ul n, T;
  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. int main()
  17. {
  18. std::ios::sync_with_stdio(false);
  19. std::cin.tie(0);
  20. iss.tie(0);
  21. oss.tie(0);
  22. std::getline(std::cin, instr, char(0));
  23. iss.str(instr);
  24. iss >> T;
  25. for (ul Case = 1; Case <= T; ++Case) {
  26. iss >> n;
  27. ul ansprev = 0;
  28. ul anscurr = 1;
  29. curr = "";
  30. for (ul i = 1; i <= n; ++i) {
  31. iss >> next;
  32. ul ansnext;
  33. if (curr != next) {
  34. ansnext = plus(ansprev, anscurr);
  35. } else {
  36. ansnext = anscurr;
  37. }
  38. std::swap(curr, next);
  39. ansprev = anscurr;
  40. anscurr = ansnext;
  41. }
  42. oss << anscurr << '\n';
  43. }
  44. std::cout << oss.str();
  45. return 0;
  46. }

F、Fake Photo 6807

现在考虑以时针走一圈的时长为“一单位时长”(也就是半天),以一圈的路程为“一单位路程”。那么可以分析得出如下结论:最优时刻一定形如,所以我们只需要把表盘等分为份,然后每一个样例只考虑个有必要考虑的时间点即可。故总时间复杂度为

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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. using lf = double;
  10. const ul mod = 43200 * 13 * 2;
  11. const ul halfmod = 43200 * 13;
  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 T;
  21. ul n;
  22. std::vector<ul> hpos;
  23. std::vector<ul> mpos;
  24. std::vector<ul> ntch(43200 * 14);
  25. std::vector<ul> ntcm(43200 * 14);
  26. char s[10];
  27. ul minus(ul a, ul b, ul mod)
  28. {
  29. return a < b ? a + mod - b : a - b;
  30. }
  31. ul plus(ul a, ul b, ul mod)
  32. {
  33. return a + b < mod ? a + b : a + b - mod;
  34. }
  35. int main()
  36. {
  37. std::ios::sync_with_stdio(false);
  38. std::cin.tie(0);
  39. iss.tie(0);
  40. oss.tie(0);
  41. std::getline(std::cin, instr, char(0));
  42. iss.str(instr);
  43. ntch.resize(0);
  44. ntcm.resize(0);
  45. for (ul i = 0; i != mod; ++i) {
  46. if (i % 13 == 0 || i % 2 == 0) {
  47. ntch.push_back(i);
  48. ntcm.push_back(12 * i % mod);
  49. }
  50. }
  51. iss >> T;
  52. for (ul Case = 1; Case <= T; ++Case) {
  53. iss >> n;
  54. hpos.resize(0);
  55. mpos.resize(0);
  56. for (ul i = 1; i <= n; ++i) {
  57. iss >> s + 1;
  58. ul t = (((s[1] - '0') * 10 + s[2] - '0') * 60 + (s[4] - '0') * 10 + s[5] - '0') * 60 + (s[7] - '0') * 10 + s[8] - '0';
  59. hpos.push_back(plus(t % 43200 * 26, halfmod));
  60. mpos.push_back(plus(t * 12 % 43200 * 26, halfmod));
  61. }
  62. std::sort(hpos.begin(), hpos.end());
  63. hpos.resize(std::unique(hpos.begin(), hpos.end()) - hpos.begin());
  64. std::sort(mpos.begin(), mpos.end());
  65. mpos.resize(std::unique(mpos.begin(), mpos.end()) - mpos.begin());
  66. ul mx = 0;
  67. ul ith = 0;
  68. ul itm = 0;
  69. for (ul i = 0; i != ntch.size(); ++i) {
  70. mx = std::max(mx, std::min(std::min(minus(ntcm[i], mpos[minus(itm, 1, mpos.size())]), minus(mpos[itm], ntcm[i])), std::min(minus(ntch[i], hpos[minus(ith, 1, hpos.size())]), minus(hpos[ith], ntch[i]))));
  71. if (ntch[i] == hpos[ith]) {
  72. ith = plus(ith, 1, hpos.size());
  73. }
  74. if (ntcm[i] == mpos[itm]) {
  75. itm = plus(itm, 1, mpos.size());
  76. }
  77. }
  78. oss << std::fixed << ' ' << std::setprecision(20) << lf(360 * (halfmod - mx)) / lf(mod) << '\n';
  79. }
  80. std::cout << oss.str();
  81. return 0;
  82. }

G、Go Running 6808

二分图最大匹配,HK算法,直接把下文当模板即可。

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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 maxn = 1e5;
  10. ul T;
  11. ul n;
  12. li t, x;
  13. std::pair<li, li> ee[maxn + 1];
  14. li as[maxn + 1];
  15. li bs[maxn + 1];
  16. ul acnt, bcnt;
  17. std::vector<ul> edges[maxn + maxn + 1];
  18. ul match[maxn + maxn + 1];
  19. std::deque<ul> queue;
  20. ul dis[maxn + maxn + 1];
  21. const ul inf = 1e9;
  22. ul al[maxn + maxn + 1];
  23. ul altim;
  24. bool search(ul curr)
  25. {
  26. al[curr] = altim;
  27. if (dis[curr] == 1) {
  28. return true;
  29. }
  30. if (curr <= acnt) {
  31. ul next = match[curr];
  32. if (altim == al[next] || dis[next] != dis[curr] - 1) {
  33. return false;
  34. }
  35. if (search(next)) {
  36. return true;
  37. }
  38. } else {
  39. for (ul next : edges[curr]) {
  40. if (altim == al[next] || dis[next] != dis[curr] - 1) {
  41. continue;
  42. }
  43. if (search(next)) {
  44. match[next] = curr;
  45. match[curr] = next;
  46. return true;
  47. }
  48. }
  49. }
  50. return false;
  51. }
  52. int main()
  53. {
  54. std::ios::sync_with_stdio(false);
  55. std::cin.tie(0);
  56. iss.tie(0);
  57. oss.tie(0);
  58. std::getline(std::cin, instr, char(0));
  59. iss.str(instr);
  60. iss >> T;
  61. for (ul Case = 1; Case <= T; ++Case) {
  62. iss >> n;
  63. for (ul i = 1; i <= n; ++i) {
  64. iss >> t >> x;
  65. ee[i].first = as[i] = t - x;
  66. ee[i].second = bs[i] = t + x;
  67. }
  68. std::sort(as + 1, as + n + 1);
  69. std::sort(bs + 1, bs + n + 1);
  70. acnt = std::unique(as + 1, as + n + 1) - as - 1;
  71. bcnt = std::unique(bs + 1, bs + n + 1) - bs - 1;
  72. for (ul i = 1; i <= acnt + bcnt; ++i) {
  73. edges[i].resize(0);
  74. match[i] = 0;
  75. }
  76. for (ul i = 1; i <= n; ++i) {
  77. ul a = std::lower_bound(as + 1, as + acnt + 1, ee[i].first) - as;
  78. ul b = std::lower_bound(bs + 1, bs + bcnt + 1, ee[i].second) - bs;
  79. edges[a].push_back(b + acnt);
  80. edges[b + acnt].push_back(a);
  81. }
  82. ul ans = 0;
  83. while (true) {
  84. assert(queue.empty());
  85. ul k = inf;
  86. for (ul i = 1; i <= acnt; ++i) {
  87. if (!match[i]) {
  88. queue.push_back(i);
  89. dis[i] = 1;
  90. } else {
  91. dis[i] = inf;
  92. }
  93. }
  94. for (ul i = acnt + 1; i <= acnt + bcnt; ++i) {
  95. dis[i] = inf;
  96. }
  97. while (queue.size()) {
  98. ul curr = queue.front();
  99. queue.pop_front();
  100. if (dis[curr] == k) {
  101. continue;
  102. }
  103. if (curr <= acnt) {
  104. for (ul next : edges[curr]) {
  105. if (dis[next] != inf) {
  106. continue;
  107. }
  108. if (!match[next]) {
  109. if (k == inf) {
  110. k = dis[curr] + 1;
  111. }
  112. }
  113. dis[next] = dis[curr] + 1;
  114. queue.push_back(next);
  115. }
  116. } else {
  117. ul next = match[curr];
  118. if (dis[next] != inf) {
  119. continue;
  120. }
  121. dis[next] = dis[curr] + 1;
  122. queue.push_back(next);
  123. }
  124. }
  125. if (k == inf) {
  126. break;
  127. }
  128. ++altim;
  129. for (ul i = acnt + 1; i <= acnt + bcnt; ++i) {
  130. if (!match[i] && dis[i] == k) {
  131. ans += search(i);
  132. }
  133. }
  134. }
  135. oss << ans << '\n';
  136. }
  137. std::cout << oss.str();
  138. return 0;
  139. }

H、Head Maker 6809

随机几棵生成树,然后检查是否可行即可。

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  5. using li = std::int32_t;
  6. using ul = std::uint32_t;
  7. using plili = std::pair<li, li>;
  8. using ppliliplili = std::pair<plili, plili>;
  9. using pulul = std::pair<ul, ul>;
  10. using pulpulul = std::pair<ul, pulul>;
  11. const ul maxn = 6;
  12. const ul maxm = 6;
  13. ul fa[maxn * maxm + 1];
  14. ul rk[maxn * maxm + 1];
  15. ul getfather(ul x)
  16. {
  17. return x == fa[x] ? x : fa[x] = getfather(fa[x]);
  18. }
  19. bool connect(ul x, ul y)
  20. {
  21. x = getfather(x);
  22. y = getfather(y);
  23. if (x == y) {
  24. return false;
  25. }
  26. if (rk[x] < rk[y]) {
  27. fa[x] = y;
  28. } else if (rk[x] > rk[y]) {
  29. fa[y] = x;
  30. } else {
  31. fa[x] = y;
  32. ++rk[y];
  33. }
  34. return true;
  35. }
  36. class vec {
  37. public:
  38. li x = 0;
  39. li y = 0;
  40. li z = 0;
  41. vec()=default;
  42. vec(li a, li b , li c): x(a), y(b), z(c) {}
  43. };
  44. vec operator+(const vec& a, const vec& b)
  45. {
  46. return vec(a.x + b.x, a.y + b.y, a.z + b.z);
  47. }
  48. vec operator*(li a, const vec& b)
  49. {
  50. return vec(a * b.x, a * b.y, a * b.z);
  51. }
  52. li operator*(const vec& a, const vec& b)
  53. {
  54. return a.x * b.x + a.y * b.y + a.z * b.z;
  55. }
  56. vec operator^(const vec& a, const vec& b)
  57. {
  58. return vec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
  59. }
  60. bool operator<(const vec& a, const vec& b)
  61. {
  62. return a.x != b.x ? a.x < b.x : (a.y != b.y ? a.y < b.y : a.z < b.z);
  63. }
  64. bool operator==(const vec& a, const vec& b)
  65. {
  66. return a.x == b.x && a.y == b.y && a.z == b.z;
  67. }
  68. bool operator!=(const vec& a, const vec& b)
  69. {
  70. return !(a == b);
  71. }
  72. class mat {
  73. public:
  74. vec x;
  75. vec y;
  76. vec z;
  77. mat()=default;
  78. mat(const vec& a, const vec& b, const vec& c): x(a), y(b), z(c) {}
  79. };
  80. vec operator*(const vec& a, const mat& b)
  81. {
  82. return a.x * b.x + a.y * b.y + a.z * b.z;
  83. }
  84. mat operator*(const mat& a, const mat& b)
  85. {
  86. return mat(a.x * b, a.y * b, a.z * b);
  87. }
  88. bool operator<(const mat& a, const mat& b)
  89. {
  90. return a.x != b.x ? a.x < b.x : (a.y != b.y ? a.y < b.y : a.z < b.z);
  91. }
  92. bool operator==(const mat& a, const mat& b)
  93. {
  94. return a.x == b.x && a.y == b.y && a.z == b.z;
  95. }
  96. std::vector<vec> dir = {vec(1, 0, 0), vec(0, 1, 0), vec(-1, 0, 0), vec(0, -1, 0), vec(0, 0, 1), vec(0, 0, -1)};
  97. std::vector<mat> state;
  98. std::map<mat, ul> stateid;
  99. std::map<vec, ul> dirid;
  100. std::vector<mat> rot = {
  101. mat(
  102. vec(0, 0, -1),
  103. vec(0, 1, 0),
  104. vec(1, 0, 0)
  105. ),
  106. mat(
  107. vec(1, 0, 0),
  108. vec(0, 0, -1),
  109. vec(0, 1, 0)
  110. ),
  111. mat(
  112. vec(0, 0, 1),
  113. vec(0, 1, 0),
  114. vec(-1, 0, 0)
  115. ),
  116. mat(
  117. vec(1, 0, 0),
  118. vec(0, 0, 1),
  119. vec(0, -1, 0)
  120. )
  121. };
  122. ul inv[24];
  123. ul bt[24];
  124. ul change[24][4];
  125. std::deque<pulul> queue;
  126. ul st[maxn * maxm + 1];
  127. bool ans = false;
  128. std::vector<pulpulul> e;
  129. std::vector<pulul> edge[maxn * maxm + 1];
  130. std::mt19937_64 rnd;
  131. ul vsz;
  132. void check() {
  133. for (ul i = e.size(); i; --i) {
  134. std::swap(e[rnd() % i], e[i - 1]);
  135. }
  136. for (ul i = 1; i <= vsz; ++i) {
  137. fa[i] = i;
  138. rk[i] = 0;
  139. edge[i].resize(0);
  140. }
  141. for (auto a : e) {
  142. if (connect(a.second.first, a.second.second)) {
  143. edge[a.second.first].push_back(pulul(a.first, a.second.second));
  144. edge[a.second.second].push_back(pulul(a.first ^ 2, a.second.first));
  145. }
  146. }
  147. while (queue.size()) {
  148. queue.pop_front();
  149. }
  150. queue.push_back(pulul(0, 1));
  151. st[1] = 0;
  152. ul set = 0;
  153. while (queue.size()) {
  154. auto p = queue.front();
  155. queue.pop_front();
  156. auto curr = p.second;
  157. auto prev = p.first;
  158. set |= 1 << bt[st[curr]];
  159. if (set == (1 << 6) - 1) {
  160. ans = true;
  161. break;
  162. }
  163. for (auto a : edge[curr]) {
  164. ul i = a.first;
  165. ul next = a.second;
  166. if (next == prev) {
  167. continue;
  168. }
  169. st[next] = change[st[curr]][i];
  170. queue.push_back(pulul(curr, next));
  171. }
  172. }
  173. }
  174. ul T;
  175. ul n, m;
  176. std::map<plili, ul> v;
  177. char str[maxm + 2];
  178. int main() {
  179. std::ios::sync_with_stdio(false);
  180. std::cin.tie(0);
  181. iss.tie(0);
  182. oss.tie(0);
  183. std::getline(std::cin, instr, char(0));
  184. iss.str(instr);
  185. rnd.seed(std::time(0));
  186. for (ul i = 0; i != 6; ++i) {
  187. dirid[dir[i]] = i;
  188. }
  189. for (auto x : dir) {
  190. for (auto y : dir) {
  191. if ((x ^ y) == vec(0, 0, 0)) {
  192. continue;
  193. }
  194. state.push_back(mat(x, y, x ^ y));
  195. }
  196. }
  197. for (ul i = 0; i != 24; ++i) {
  198. stateid[state[i]] = i;
  199. }
  200. for (ul i = 0; i != 24; ++i) {
  201. for (ul j = 0; j != 24; ++j) {
  202. if (state[i] * state[j] == mat(vec(1, 0, 0), vec(0, 1, 0), vec(0, 0, 1))) {
  203. inv[i] = j;
  204. }
  205. }
  206. bt[i] = dirid[vec(0, 0, -1) * state[inv[i]]];
  207. }
  208. for (ul i = 0; i != 24; ++i) {
  209. for (ul j = 0; j != 4; ++j) {
  210. change[i][j] = stateid[state[i] * rot[j]];
  211. }
  212. }
  213. iss >> T;
  214. for (ul Case = 1; Case <= T; ++Case) {
  215. iss >> n >> m;
  216. v.clear();
  217. vsz = 0;
  218. for (ul i = 1; i <= n; ++i) {
  219. iss >> str + 1;
  220. for (ul j = 1; j <= m; ++j) {
  221. if (str[j] == '1') {
  222. ++vsz;
  223. v[plili(i, j)] = vsz;
  224. }
  225. }
  226. }
  227. e.resize(0);
  228. for (const auto& a : v) {
  229. auto curr = a.first;
  230. for (ul i = 0; i != 2; ++i) {
  231. auto next = plili(curr.first + dir[i].x, curr.second + dir[i].y);
  232. if (v.find(next) != v.end()) {
  233. e.push_back(pulpulul(i, pulul(a.second, v[next])));
  234. }
  235. }
  236. }
  237. ans = false;
  238. for (ul cnt = 0; cnt != 10; ++cnt) {
  239. check();
  240. if (ans) {
  241. oss << "Yes\n";
  242. break;
  243. }
  244. }
  245. if (!ans) {
  246. oss << "No\n";
  247. }
  248. }
  249. std::cout << oss.str();
  250. return 0;
  251. }

I、Imperative Meeting 6810

官方题解如下:
新建位图图像.png-179.5kB

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  5. using li = std::int32_t;
  6. using ul = std::uint32_t;
  7. using ll = std::int64_t;
  8. using ull = std::uint64_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 minus(ul a, ul b)
  15. {
  16. return a < b ? a + mod - b : a - b;
  17. }
  18. ul mul(ul a, ul b)
  19. {
  20. return ull(a) * ull(b) % mod;
  21. }
  22. void exgcd(li a, li b, li& x, li& y)
  23. {
  24. if (b) {
  25. exgcd(b, a % b, y, x);
  26. y -= a / b * x;
  27. } else {
  28. x = 1;
  29. y = 0;
  30. }
  31. }
  32. ul inverse(ul a)
  33. {
  34. li x, y;
  35. exgcd(a, mod, x, y);
  36. return x < 0 ? x + li(mod) : x;
  37. }
  38. const ul maxn = 1e6;
  39. ul n, m;
  40. ul T;
  41. ul f[maxn + 1];
  42. ul sz[maxn + 1];
  43. ul h[maxn + 1];
  44. ul fac[maxn + 1];
  45. ul fiv[maxn + 1];
  46. ul bi(ul a, ul b)
  47. {
  48. return a >= b ? mul(fac[a], mul(fiv[a - b], fiv[b])) : ul(0);
  49. }
  50. int main() {
  51. std::ios::sync_with_stdio(false);
  52. std::cin.tie(0);
  53. iss.tie(0);
  54. oss.tie(0);
  55. std::getline(std::cin, instr, char(0));
  56. iss.str(instr);
  57. fac[0] = 1;
  58. for (ul i = 1; i <= maxn; ++i) {
  59. fac[i] = mul(fac[i - 1], i);
  60. }
  61. fiv[maxn] = inverse(fac[maxn]);
  62. for (ul i = maxn; i >= 1; --i) {
  63. fiv[i - 1] = mul(fiv[i], i);
  64. }
  65. iss >> T;
  66. for (ul Case = 1; Case <= T; ++Case) {
  67. iss >> n >> m;
  68. for (ul i = 2; i <= n; ++i) {
  69. iss >> f[i];
  70. sz[i] = 0;
  71. }
  72. for (ul i = n; i >= 2; --i) {
  73. ++sz[i];
  74. sz[f[i]] += sz[i];
  75. }
  76. sz[1] = n;
  77. ul p = m - 1 >> 1;
  78. if (p >= 1) {
  79. h[1] = bi(n - 1, m - 1);
  80. for (ul s = 2; s <= n; ++s) {
  81. h[s] = minus(h[s - 1], mul(bi(s - 2, p - 1), bi(n - s, m - p - 1)));
  82. }
  83. } else {
  84. for (ul s = 1; s <= n; ++s) {
  85. h[s] = 0;
  86. }
  87. }
  88. ul ans = 0;
  89. for (ul i = 2; i <= n; ++i) {
  90. ul s = sz[i];
  91. ans = plus(plus(ans, plus(mul(s, h[s]), mul(n - s, h[n - s]))), (~m & 1) ? mul(mul(bi(s, m >> 1), bi(n - s, m >> 1)), m >> 1) : ul(0));
  92. }
  93. oss << ans << '\n';
  94. }
  95. std::cout << oss.str();
  96. return 0;
  97. }

K、Kindergarten Physics 6812

傻逼题

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  5. using li = std::int32_t;
  6. using ul = std::uint32_t;
  7. using ll = std::int64_t;
  8. using ull = std::uint64_t;
  9. ul T;
  10. int main() {
  11. std::ios::sync_with_stdio(false);
  12. std::cin.tie(0);
  13. iss.tie(0);
  14. oss.tie(0);
  15. std::getline(std::cin, instr, char(0));
  16. iss.str(instr);
  17. iss >> T;
  18. for (ul Case = 1; Case <= T; ++Case) {
  19. ul a, b, d, t0;
  20. iss >> a >> b >> d >> t0;
  21. oss << d << '\n';
  22. }
  23. std::cout << oss.str();
  24. return 0;
  25. }

L、Last Problem 6813

直接看代码

  1. #include <bits/stdc++.h>
  2. std::stringstream iss;
  3. std::stringstream oss;
  4. std::string instr;
  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. using plili = std::pair<li, li>;
  10. ul n;
  11. const ul maxn = 100;
  12. std::vector<plili> v[maxn + 1];
  13. int main()
  14. {
  15. std::ios::sync_with_stdio(false);
  16. std::cin.tie(0);
  17. iss.tie(0);
  18. oss.tie(0);
  19. std::getline(std::cin, instr, char(0));
  20. iss.str(instr);
  21. iss >> n;
  22. v[n].push_back(plili(0, 0));
  23. for (ul i = n; i >= 1; --i) {
  24. std::sort(v[i].begin(), v[i].end());
  25. v[i].resize(std::unique(v[i].begin(), v[i].end()) - v[i].begin());
  26. for (const auto& p : v[i]) {
  27. if (i >= 1) {
  28. v[i - 1].push_back(plili(p.first - 1, p.second));
  29. }
  30. if (i >= 2) {
  31. v[i - 2].push_back(plili(p.first, p.second - 1));
  32. }
  33. if (i >= 3) {
  34. v[i - 3].push_back(plili(p.first, p.second + 1));
  35. }
  36. if (i >= 4) {
  37. v[i - 4].push_back(plili(p.first + 1, p.second));
  38. }
  39. }
  40. }
  41. for (ul i = 1; i <= n; ++i) {
  42. for (const auto& p : v[i]) {
  43. oss << p.first << ' ' << p.second << ' ' << i << '\n';
  44. }
  45. }
  46. std::cout << oss.str();
  47. return 0;
  48. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注