[关闭]
@Falsyta 2016-02-12T14:45:17.000000Z 字数 46614 阅读 1928

颓废实录

OI


难度说明

[0-] 一眼题
[0-+] 唯一难度是代码的题目
[0] 极其显然的题目
[0+] 或许不是很简单但个人认为没有太大价值的题目
[0++] 或许有些难度但总觉得思路过于模板/陈旧的题目
[1-] 稍微想想就显然的题目
[1] 需要一会思考然后显然的题目
[1+] 需要好好想想的题目
[1++] 好好想想后依然难度不小的题目
<1++的是大部分自己独立想出来的题目
[2--] 为什么我这都不会啊啊(傲娇(才不是呢!
[2-] 思路似乎不那么显然的题目(其实是因为我太弱了)
[2-+] 思路有点厉害还难写的题目
[2] 思路有点优美的题目
[2+] 思路优美的题目
[2++] 思路优美还难写的题目
[3] 吓人的题目

进度

ASC01: 6/8
ASC02: 5/8
ASC30: 4/10
PA2011: 15/25 https://zybuluo.com/Falsyta/note/202488
AMPPZ2014: 6/11 https://zybuluo.com/Falsyta/note/202187
2014年国家集训队作业: 16/158
TCO 2012 L3: 5/12
TCO 2013 L3: 12/12 https://zybuluo.com/Falsyta/note/182557

尚未填坑

BOI2014 portals 传送门只用来横着从一堵墙到另外一堵墙吧……似乎BFS就好了。
BOI2014 postman 欧拉回路可以一遍DFS求吧。
ONTAK2015 bad 感觉在next树上做个DP就好了?(雾……
ONTAK2015 baj 似乎直接线段树做过去就好了吧……
ONTAK2015 cie 暴力枚举一个断点,剩下一个预处理什么的似乎就好了
ONTAK2015 stu 似乎是裸线段树……?

目录

Sept 2015 https://zybuluo.com/Falsyta/note/185778

[0]CF256D Liars and Serge
[2-]CF325E The Red Button
[0-+]CF335D Rectangles and Square
[1-]TCO2012 Round 1A EllysLights
[0]CF305E Playing with String
[2-]CF235E Number Challenge
[2-]CF238E Meeting Her
[0-]CF582A GCD Table
[0]CF582B Once Again...
[2-+]CF317E Princess and Her Shadow
[2-]PA2011 pec
[1-]PA2011 pod
[0]CF263E Rhombus
[1-]CF360D Levko and Sets
[2-]PA2011 prz
[2-]TCO2012 Round 1B FoxAndPhotography
[0+]BZOJ2393
[2-+]TCO2012 Round 2A EvenPaths
[0]TCO2012 Round 1C PasswordXPalindrome
[1-]PA2011 pie
[0-]CF585B Phillip and Trains
[1]CF585C Alice, Bob, Oranges and Apples
[0]CF585D Lizard Era: Beginning
[1]ASC02 A Non Absorbing DFA
[2++]PA2009 sza
[1+]CC AUTHEN
[1]CC SKIRES
[2]CC E5
[3-]CEOI2015 indcyc
[1]AMPPZ2014 ben
[0+]AMPPZ2014 cen
[1]AMPPZ2014 glo
[0]AMPPZ2014 fil
[1]AMPPZ2014 ins
[2]BOI2014 sequence
[2]AMPPZ2014 hit
[1]PA2011 bwp
[1+]PA2011 kan
[1]PA2011 aut
[0]CF590A Median Smoothing
[0]CF590C Three States
[0]CF590D Top Secret Task
[1]PA2011 cia
[1]USACO JAN09 Safe Travel
[0+]PA2011 wyb
[1]SRM533 L3 Pikachu
[2-]USACO DEC05 Cow Patterns
[2--]USACO NOV07 Best Cow Line
[0]ASC30 F Sqrt Nim
[0]ASC30 D Currency Exchange
[0]ASC30 B Signed Derangements
[1]ASC30 I Segment Transformation
[1-]PA2011 bio
[2-]PA2011 wyz

10.1 木曜日

CF256D Liars and Serge

傻逼打表题……(不过其实似乎迭代的话不打也是能过的……

CF325E The Red Button

缩成一个点后问题变成了求欧拉回路。
注意到如果在不同的回路里,我们只需要交换它们的后继就可以合并两个回路了。

  1. # include <cstdio>
  2. # include <cstring>
  3. # define NR 100100
  4. int p[NR], n;
  5. void dfs (int x)
  6. {
  7. if (p[x] != -1) return ;
  8. int y = (x + n / 2) % n;
  9. if (p[y] != -1) dfs (p[x] = (2 * x + (p[y] == 2 * x % n)) % n);
  10. else
  11. {
  12. dfs (p[x] = 2 * x % n);
  13. if (p[y] == -1) p[y] = p[x], dfs (p[x] = (2 * x + 1) % n);
  14. }
  15. }
  16. int main ()
  17. {
  18. scanf ("%d", &n);
  19. if (n % 2) return puts ("-1"), 0;
  20. memset (p, -1, sizeof (p));
  21. dfs (0), printf ("0 ");
  22. for (int i = p[0]; i; i = p[i]) printf ("%d ", i);
  23. printf ("0\n");
  24. return 0;
  25. }

CF335D Rectangles and Square

考虑暴力枚举正方形的左边界,以此可以很容易地判定上下右边界是否合法以及正方形是否被填满。
时间复杂度

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. # include <vector>
  5. # include <iostream>
  6. using namespace std;
  7. # define REP(i, n) for (int i = 1; i <= n; i ++)
  8. # define REP_0(i, n) for (int i = 0; i < n; i ++)
  9. # define REP_0N(i, n) for (int i = 0; i <= n; i ++)
  10. # define FOR(i, a, b) for (int i = a; i <= b; i ++)
  11. # define W 3000
  12. # define NR 401000
  13. int su[W + 2][W + 2], xsz, ysz, belX[W + 2][W + 2], belY[W + 2][W + 2], li[NR], len, n;
  14. struct Rect
  15. {
  16. int xl, xr, yl, yr;
  17. void init ()
  18. {
  19. scanf ("%d%d%d%d", &xl, &yl, &xr, &yr);
  20. FOR (i, xl + 1, xr) FOR (j, yl + 1, yr) ++ su[i][j];
  21. }
  22. } a[NR];
  23. struct Seg
  24. {
  25. int l, r, t;
  26. Seg () {l = r = t = 0;}
  27. Seg (int _l, int _r, int _t) {l = _l, r = _r, t = _t;}
  28. } sX[NR], sY[NR];
  29. vector <int> xP[W + 2];
  30. inline bool cmp (Seg a, Seg b)
  31. {
  32. if (a.t != b.t) return a.t < b.t;
  33. if (a.l != b.l) return a.l < b.l;
  34. return a.r > b.r;
  35. }
  36. inline int sum (int xl, int xr, int yl, int yr) {return su[xr][yr] - su[xl - 1][yr] - su[xr][yl - 1] + su[xl - 1][yl - 1];}
  37. int main ()
  38. {
  39. scanf ("%d", &n);
  40. REP (i, n)
  41. {
  42. a[i].init ();
  43. sX[2 * i - 1] = Seg (a[i].xl, a[i].xr, a[i].yl);
  44. sX[2 * i] = Seg (a[i].xl, a[i].xr, a[i].yr);
  45. sY[2 * i - 1] = Seg (a[i].yl, a[i].yr, a[i].xl);
  46. sY[2 * i] = Seg (a[i].yl, a[i].yr, a[i].xr);
  47. }
  48. REP (i, W) REP (j, W) su[i][j] += su[i - 1][j] + su[i][j - 1] - su[i - 1][j - 1];
  49. sort (sX + 1, sX + 2 * n + 1, cmp);
  50. sort (sY + 1, sY + 2 * n + 1, cmp);
  51. sX[2 * n + 1].t = sY[2 * n + 1].t = -1;
  52. REP (i, 2 * n)
  53. {
  54. belX[sX[i].l][sX[i].t] = belX[sX[i].r][sX[i].t] = ++ xsz;
  55. while (sX[i].t == sX[i + 1].t && sX[i + 1].l <= sX[i].r)
  56. ++ i, belX[sX[i].l][sX[i].t] = belX[sX[i].r][sX[i].t] = xsz;
  57. }
  58. REP (i, 2 * n)
  59. {
  60. belY[sY[i].t][sY[i].l] = belY[sY[i].t][sY[i].r] = ++ ysz; int t = i, R = sY[i].r;
  61. while (sY[i].t == sY[i + 1].t && sY[i + 1].l <= R)
  62. R = max (R, sY[++ i].r), belY[sY[i].t][sY[i].l] = belY[sY[i].t][sY[i].r] = ysz;
  63. FOR (j, t, i) xP[sY[j].t].push_back (sY[j].l), xP[sY[j].t].push_back (sY[j].r);
  64. }
  65. REP_0N (x, W)
  66. {
  67. sort (xP[x].begin (), xP[x].end ());
  68. xP[x].erase (unique (xP[x].begin (), xP[x].end ()), xP[x].end ());
  69. int tl = xP[x].size ();
  70. REP_0 (i, tl)
  71. FOR (j, i + 1, tl - 1)
  72. {
  73. int yi = xP[x][i], yj = xP[x][j], z = yj - yi;
  74. if (belY[x][yi] != belY[x][yj]) break;
  75. if (belX[x][yi] != belX[x + z][yi] || belX[x][yj] != belX[x + z][yj] || belY[x + z][yi] != belY[x + z][yj])
  76. continue;
  77. if (sum (x + 1, x + z, yi + 1, yj) == z * z)
  78. {
  79. REP (id, n)
  80. if (x <= a[id].xl && a[id].xr <= x + z && yi <= a[id].yl && a[id].yr <= yj)
  81. li[++ len] = id;
  82. printf ("YES %d\n", len);
  83. REP (t, len) printf ("%d ", li[t]);
  84. return 0;
  85. }
  86. }
  87. }
  88. puts ("NO");
  89. return 0;
  90. }

TCO2012 Round 1A EllysLights

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <string>
  4. # include <vector>
  5. using namespace std;
  6. # define REP(i, n) for (int i = 1; i <= n; i ++)
  7. # define REP_0(i, n) for (int i = 0; i < n; i ++)
  8. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  9. # define ER 10000
  10. # define PR 200
  11. # define v g[i].y
  12. struct Edge {int y, frt, val; void set (int yr, int fr, int vl) {y = yr, frt = fr, val = vl;}} g[ER];
  13. int pos[PR], gsz;
  14. inline void AE (int x, int y, int z) {g[++ gsz].set (y, pos[x], z), pos[x] = gsz;}
  15. class EllysLights
  16. {
  17. private:
  18. int __cnt[2], q[PR];
  19. bool vis[PR], state[PR], failed, col[PR];
  20. vector <int> ctrled[PR], ctrl[PR];
  21. void dfs (int x, bool c)
  22. {
  23. if (vis[x]) {if (c != col[x]) failed = true; return ;}
  24. vis[x] = true, ++ __cnt[col[x] = c];
  25. REP_G (i, x) dfs (v, c ^ g[i].val);
  26. }
  27. public:
  28. int getMinimum (string init, vector <string> trans)
  29. {
  30. int n = init.length (), m = trans.size ();
  31. REP_0 (i, m)
  32. REP_0 (j, n)
  33. if (trans[i][j] == 'Y')
  34. ctrled[j + 1].push_back (i + 1),
  35. ctrl[i + 1].push_back (j + 1);
  36. int ans = 0, head = 1, tail = 0;
  37. REP (i, n) state[i] = init[i - 1] == 'Y';
  38. REP (i, n)
  39. {
  40. if (state[i])
  41. {
  42. if (!ctrled[i].size ()) return -1;
  43. if (ctrled[i].size () == 1) q[++ tail] = i;
  44. }
  45. else
  46. {
  47. if (!ctrled[i].size ()) vis[m + i] = true;
  48. if (ctrled[i].size () == 1) q[++ tail] = i;
  49. }
  50. }
  51. while (head <= tail)
  52. {
  53. int x = q[head ++]; vis[m + x] = true;
  54. int y = ctrled[x][0];
  55. if (vis[y]) continue;
  56. REP_0 (i, ctrl[y].size ())
  57. if (ctrl[y][i] != x)
  58. {
  59. int z = ctrl[y][i]; state[z] ^= state[x];
  60. REP_0 (j, ctrled[z].size ()) if (ctrled[z][j] == y) ctrled[z].erase (ctrled[z].begin () + j);
  61. if (state[z])
  62. {
  63. if (!ctrled[z].size ()) return -1;
  64. if (ctrled[z].size () == 1) q[++ tail] = z;
  65. }
  66. else
  67. {
  68. if (!ctrled[z].size ()) vis[m + z] = true;
  69. if (ctrled[z].size () == 1) q[++ tail] = z;
  70. }
  71. }
  72. vis[y] = true, ans += state[x];
  73. }
  74. head = 1, tail = 0;
  75. REP (i, n) if (!vis[m + i]) AE (ctrled[i][0], ctrled[i][1], state[i]), AE (ctrled[i][1], ctrled[i][0], state[i]);
  76. REP (i, m) if (!vis[i]) __cnt[0] = __cnt[1] = 0, dfs (i, 0), ans += min (__cnt[0], __cnt[1]);
  77. if (failed) return -1;
  78. return ans;
  79. }
  80. };

10.2 金曜日

机房好吵>_<

CF305E Playing with String

一开始读错题了QAQ

显然只需要满足就是可选的。
把连续可选的一段缩在一起,显然段与段之间是相互独立的。
函数一算就没了。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  7. # define RST(a) memset (a, 0, sizeof (a))
  8. # define NR 20000
  9. char s[NR];
  10. bool vis[NR];
  11. int sg[NR], cov[NR], last[NR];
  12. int main ()
  13. {
  14. scanf ("%s", s + 1); int n = strlen (s + 1);
  15. sg[0] = 0, sg[1] = 1;
  16. FOR (i, 2, n)
  17. {
  18. RST (vis);
  19. REP (j, i) vis[sg[max (0, j - 2)] ^ sg[max (0, i - j - 1)]] = true;
  20. while (vis[sg[i]]) ++ sg[i];
  21. }
  22. int lst = -1, ans = 0;
  23. FOR (i, 2, n - 1)
  24. {
  25. if (s[i - 1] == s[i + 1]) {if (lst == -1) lst = i;}
  26. else if (lst != -1)
  27. {
  28. FOR (j, lst, i - 1) cov[j] = i - lst;
  29. ans ^= sg[i - lst], lst = -1;
  30. }
  31. last[i] = lst;
  32. }
  33. if (lst != -1)
  34. {
  35. FOR (i, lst, n - 1) cov[i] = n - lst;
  36. ans ^= sg[n - lst];
  37. }
  38. if (!ans) return puts ("Second"), 0;
  39. FOR (i, 2, n - 1)
  40. {
  41. if (s[i - 1] != s[i + 1]) continue;
  42. int j = i - last[i] + 1;
  43. if (!(ans ^ sg[cov[i]] ^ sg[max (0, j - 2)] ^ sg[max (0, cov[i] - j - 1)]))
  44. return printf ("First\n%d\n", i), 0;
  45. }
  46. return 0;
  47. }

10.3 土曜日

CF235E Number Challenge

自己为什么这种傻逼题都不会做啊QAQ

  1. # include <cstdio>
  2. # define REP(i, n) for (int i = 1; i <= n; i ++)
  3. # define FOR(i, a, b) for (int i = a; i <= b; i ++)
  4. # define NR 2010
  5. # define QR 4010000
  6. int A, B, C, f[QR], g[QR], pr[NR], psz, mu[NR];
  7. bool vis[NR];
  8. int main ()
  9. {
  10. scanf ("%d%d%d", &A, &B, &C); int AB = A * B;
  11. REP (i, A) REP (j, B) f[i * j] ++;
  12. mu[1] = 1;
  13. REP (i, C)
  14. {
  15. int t = 0;
  16. for (int j = 1; i * j <= C; j ++) t += C / (i * j);
  17. if (i != 1)
  18. {
  19. if (!vis[i]) pr[++ psz] = i, mu[i] = -1;
  20. for (int j = 1; j <= psz && i * pr[j] <= C; j ++)
  21. {
  22. vis[i * pr[j]] = true;
  23. if (i % pr[j] == 0) {mu[i * pr[j]] = 0; break;}
  24. else mu[i * pr[j]] = - mu[i];
  25. }
  26. }
  27. t *= mu[i]; int tl = AB / i;
  28. REP (j, tl) g[i * j] += t;
  29. }
  30. int ans = 0;
  31. REP (i, AB)
  32. {
  33. int h = 0, tl = AB / i;
  34. REP (j, tl) h += f[i * j];
  35. ans += g[i] * h;
  36. }
  37. printf ("%u\n", (unsigned) ans & ((1 << 30) - 1));
  38. return 0;
  39. }

CF238E Meeting Her

自己为什么这种傻逼题都不会做啊QAQ

对于每个公交线路建出最短路图。

考虑最坏步可以到达的点。
若一个在公交线路的割点,满足从的所有路径上都至少有一个最坏步可以到达的点,则最坏步可以到达
然后就暴力。
话说DAG中判割点有什么不用算方案数的好方法啊……

  1. # include <cstdio>
  2. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  3. # define NR 300
  4. template <class T0, class T1> inline bool RlxN (T0 &x, const T1 &y) {if (x > y) return x = y, true; return false;}
  5. const int inf = (1 << 30) - 2;
  6. int n, m, S, T, K, cur, g[NR][NR], d[NR][NR], fv[NR], sR[NR], tR[NR];
  7. bool e[NR][NR], reach[NR], newr[NR];
  8. bool dfs (int x)
  9. {
  10. if (x == tR[cur]) return reach[x];
  11. if (fv[x] != -1) return fv[x];
  12. bool res = true;
  13. REP (v, n) if (e[x][v] && g[sR[cur]][x] + 1 + g[v][tR[cur]] == g[sR[cur]][tR[cur]]) res &= dfs (v);
  14. res |= reach[x];
  15. if (res && d[sR[cur]][x] * d[x][tR[cur]] == d[sR[cur]][tR[cur]]) newr[x] = true;
  16. return fv[x] = res;
  17. }
  18. int main ()
  19. {
  20. scanf ("%d%d%d%d", &n, &m, &S, &T);
  21. if (S == T) return puts ("0"), 0;
  22. int t1, t2;
  23. REP (i, n) REP (j, n) g[i][j] = inf;
  24. REP (i, m) scanf ("%d%d", &t1, &t2), g[t1][t2] = d[t1][t2] = 1, e[t1][t2] = true;
  25. REP (k, n)
  26. REP (i, n)
  27. REP (j, n)
  28. {
  29. if (g[i][j] > g[i][k] + g[k][j]) g[i][j] = g[i][k] + g[k][j], d[i][j] = d[i][k] * d[k][j];
  30. else if (g[i][j] == g[i][k] + g[k][j]) d[i][j] += d[i][k] * d[k][j];
  31. }
  32. REP (i, n) g[i][i] = 0, d[i][i] = 1;
  33. scanf ("%d", &K);
  34. REP (i, K) scanf ("%d%d", &sR[i], &tR[i]);
  35. reach[T] = true;
  36. REP (i, n)
  37. {
  38. for (cur = 1; cur <= K; ++ cur)
  39. {
  40. if (d[sR[cur]][tR[cur]] == 0) continue;
  41. REP (j, n) fv[j] = -1; dfs (sR[cur]);
  42. }
  43. REP (j, n) reach[j] = newr[j];
  44. if (reach[S]) return printf ("%d\n", i), 0;
  45. }
  46. puts ("-1");
  47. return 0;
  48. }

CF582A GCD Table

当时想都没想就一个map上去……
后来发现似乎是统计出现奇数次的数就好了……

  1. # include <cstdio>
  2. # include <cassert>
  3. # include <map>
  4. # define REP(i, n) for (int i = 1; i <= n; i ++)
  5. using namespace std;
  6. map <int, int> vis;
  7. int li[1000010], len, n;
  8. int gcx (int a, int b) {return !b ? a : gcx (b, a % b);}
  9. int main ()
  10. {
  11. scanf ("%d", &n); int N = n * n, ta;
  12. REP (i, N) scanf ("%d", &ta), ++ vis[ta];
  13. for (map <int, int>::reverse_iterator it = vis.rbegin (); it != vis.rend ();)
  14. {
  15. if (!it->second) {++ it; continue;}
  16. it->second --;
  17. printf ("%d ", li[++ len] = it->first);
  18. REP (i, len - 1) vis[gcx (li[len], li[i])] -= 2;
  19. }
  20. puts ("");
  21. return 0;
  22. }

CF582B Once Again...

也不知道这种一眼大暴力为什么自己1h才A。

  1. # include <cstdio>
  2. # include <algorithm>
  3. using namespace std;
  4. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  5. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  6. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  7. # define REP_0N(i, n) for (int i = 0; i <= n; ++ i)
  8. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  9. # define W 300
  10. int n, T, cnt[400], f[400], fv[400], a[400];
  11. int main ()
  12. {
  13. scanf ("%d%d", &n, &T);
  14. int N = n * n;
  15. if (N * 3 > T * n) N = T * n;
  16. REP (i, n) scanf ("%d", &a[i]), ++ cnt[a[i]];
  17. REP (i, N)
  18. {
  19. int w = a[(i - 1) % n + 1];
  20. ++ f[w];
  21. REP_0 (j, w) f[w] = max (f[w], f[j] + 1);
  22. }
  23. if (N == T * n)
  24. {
  25. int ans = 0;
  26. REP_0N (i, W) ans = max (ans, f[i]);
  27. return printf ("%d\n", ans), 0;
  28. }
  29. REP_D (i, N)
  30. {
  31. int w = a[(i - 1) % n + 1];
  32. ++ fv[w];
  33. FOR (j, w + 1, W) fv[w] = max (fv[w], fv[j] + 1);
  34. }
  35. int ans = 0;
  36. REP (i, W)
  37. {
  38. int f0 = 0, f1 = 0;
  39. REP_0N (j, i) f0 = max (f0, f[j]);
  40. FOR (j, i, W) f1 = max (f1, fv[j]);
  41. ans = max (ans, f0 + f1 + cnt[i] * (T - n * 2));
  42. }
  43. printf ("%d\n", ans);
  44. return 0;
  45. }

10.4 日曜日

CF317E Princess and Her Shadow

写之前:哎他们写的为什么这么长呀0.0
写之后:我写的为毛这么长T T

结合昨天晚上爆炸的CF,得出了自己应该退役的好消息。

一直想怎么才能在树林里绕……却连可以走出树林这种事都不知道……
追影子走追出树林。
然后乱撞就行了……

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; i ++)
  6. # define REP_0(i, n) for (int i = 0; i < n; i ++)
  7. # define NR 500
  8. # define SR 200000
  9. struct Poi {int x, y; Poi () {x = y = 0;} Poi (int _x, int _y) : x(_x), y(_y) {}} q[SR], po[NR];
  10. int n, vX, vY, sX, sY, cX, cY, minX, minY, maxX, maxY, up, dw, lf, rt;
  11. int pre[NR][NR], li[SR], len, qi[SR];
  12. bool tree[NR][NR];
  13. int dx[] = {0, 0, -1, 1};
  14. int dy[] = {-1, 1, 0, 0};
  15. char dirc[] = "DULR";
  16. # define W 400
  17. inline int sgn (int x) {return x > 0 ? 1 : x < 0 ? -1 : 0;}
  18. inline bool existTree (int x, int y) {if (x < minX || y < minY || x > maxX || y > maxY) return false; return tree[x][y];}
  19. void bfs ()
  20. {
  21. int head = 1, tail = 1; q[1] = Poi (vX, vY), pre[vX][vY] = -1;
  22. while (head <= tail)
  23. {
  24. Poi u = q[head ++];
  25. REP_0 (d, 4)
  26. {
  27. int _x = u.x + dx[d], _y = u.y + dy[d];
  28. if (!existTree (_x, _y) && !pre[_x][_y] && 0 <= _x && _x <= W && 0 <= _y && _y <= W)
  29. q[++ tail] = Poi (_x, _y), pre[_x][_y] = d + 1;
  30. }
  31. }
  32. }
  33. # define pc putchar
  34. inline int area (int x, int y) {return (x < minX ? -3 : x > maxX ? 3 : 0) + (y < minY ? -1 : y > maxY ? 1 : 0);}
  35. inline int dLf () {vY --, sY --, pc (dirc[0]);}
  36. inline int dRt () {vY ++, sY ++, pc (dirc[1]);}
  37. inline int dUp () {vX --, sX --, pc (dirc[2]);}
  38. inline int dDw () {vX ++, sX ++, pc (dirc[3]);}
  39. void towardsX (int Sj, int Tj) {while ((area (sX, sY) + 4) / 3 != Tj || (area (vX, vY) + 4) / 3 != Tj) Sj < Tj ? dDw () : dUp ();}
  40. void towardsY (int Si, int Ti) {while ((area (sX, sY) + 4) % 3 != Ti || (area (vX, vY) + 4) % 3 != Ti) Si < Ti ? dRt () : dLf ();}
  41. void moveTo (int S, int T)
  42. {
  43. if (S == T) return ;
  44. if (S * T == -1)
  45. {
  46. while (area (sX, sY) > -2 || area (vX, vY) > -2) dUp ();
  47. if (S == -1) while (area (sX, sY) != -2 || area (vX, vY) != -2) dRt ();
  48. else while (area (sX, sY) != -4 || area (vX, vY) != -4) dLf ();
  49. }
  50. else if (S * T == -9)
  51. {
  52. while ((area (sX, sY) + 1) % 3 || (area (vX, vY) + 1) % 3) dLf ();
  53. if (S == -3) while (area (sX, sY) != 2 || area (vX, vY) != 2) dDw ();
  54. else while (area (sX, sY) != -4 || area (vX, vY) != -4) dUp ();
  55. }
  56. else
  57. {
  58. int Si = (S + 4) % 3, Sj = (S + 4) / 3, Ti = (T + 4) % 3, Tj = (T + 4) / 3;
  59. bool bS = S % 3 == 0 || abs (S) < 2, bT = T % 3 == 0 || abs (T) < 2, ord = 0;
  60. if (!bS && !bT) ord = 0;
  61. else if (!bS) ord = T % 3 != 0;
  62. else ord = S % 3 == 0;
  63. ord ? (towardsY (Si, Ti), towardsX (Sj, Tj)) : (towardsX (Sj, Tj), towardsY (Si, Ti));
  64. }
  65. }
  66. void move ()
  67. {
  68. if (!pre[sX][sY]) {puts ("-1"); return ;}
  69. for (int x = sX, y = sY; pre[x][y] != -1;)
  70. li[++ len] = pre[x][y] - 1, x -= dx[li[len]], y -= dy[li[len]];
  71. int hi = 1, ti = 0;
  72. vX = sX, vY = sY;
  73. REP (i, len)
  74. {
  75. if (i < len - i + 1) swap (li[i], li[len - i + 1]);
  76. int _x = sX + dx[li[i]], _y = sY + dy[li[i]];
  77. if (!existTree (_x, _y)) sX = _x, sY = _y, qi[++ ti] = li[i];
  78. }
  79. while ((vX != sX || vY != sY) && (area (sX, sY) != area (vX, vY) || area (sX, sY) == 0) && hi <= ti)
  80. {
  81. int d = qi[hi ++], _x = sX + dx[d], _y = sY + dy[d];
  82. vX += dx[d], vY += dy[d];
  83. if (!existTree (_x, _y)) sX = _x, sY = _y, qi[++ ti] = d;
  84. }
  85. if (hi > ti)
  86. {
  87. if (sX != vX || sY != vY) puts ("-1");
  88. else
  89. {
  90. REP (i, len) printf ("%c", dirc[li[i]]);
  91. REP (i, hi - 1) printf ("%c", dirc[qi[i]]);
  92. }
  93. return ;
  94. }
  95. REP (i, len) printf ("%c", dirc[li[i]]);
  96. REP (i, hi - 1) printf ("%c", dirc[qi[i]]);
  97. moveTo (area (sX, sY), sgn (vX - sX) * 3 + sgn (vY - sY));
  98. if (vX != sX)
  99. {
  100. int t = vX < sX ? up : dw;
  101. while (sY < po[t].y) dRt ();
  102. while (sY > po[t].y) dLf ();
  103. if (vX < sX) {while (sX + 1 < po[t].x) dDw (); while (vX < sX) pc (dirc[3]), vX ++;}
  104. else {while (sX - 1 > po[t].x) dUp (); while (vX > sX) pc (dirc[2]), vX --;}
  105. }
  106. if (vY != sY)
  107. {
  108. int t = vY < sY ? lf : rt;
  109. while (sY < po[t].y) dRt ();
  110. while (sY > po[t].y) dLf ();
  111. vY < sY ? dLf () : dRt ();
  112. while (sX < po[t].x) dDw ();
  113. while (sX > po[t].x) dUp ();
  114. if (vY < sY) while (vY < sY) pc (dirc[1]), vY ++;
  115. else while (vY > sY) pc (dirc[0]), vY --;
  116. }
  117. }
  118. inline void proc (int &x, int &y) {x -= cX, y -= cY;}
  119. int main ()
  120. {
  121. scanf ("%d%d%d%d%d", &vX, &vY, &sX, &sY, &n);
  122. if (!n) {if (vX != sX || vY != sY) puts ("-1"); return 0;}
  123. up = dw = lf = rt = -1, minX = minY = 200, maxX = maxY = -200;
  124. REP (i, n)
  125. {
  126. scanf ("%d%d", &po[i].x, &po[i].y);
  127. minX = min (minX, po[i].x), minY = min (minY, po[i].y);
  128. maxX = max (maxX, po[i].x), maxY = max (maxY, po[i].y);
  129. if (up == -1 || po[up].x > po[i].x) up = i;
  130. if (dw == -1 || po[dw].x < po[i].x) dw = i;
  131. if (lf == -1 || po[lf].y > po[i].y) lf = i;
  132. if (rt == -1 || po[rt].y < po[i].y) rt = i;
  133. }
  134. cX = min (minX, min (sX, vX)) - 10, cY = min (minY, min (sY, vY)) - 10;
  135. REP (i, n) proc (po[i].x, po[i].y), tree[po[i].x][po[i].y] = true;
  136. proc (vX, vY), proc (sX, sY), proc (minX, minY), proc (maxX, maxY);
  137. bfs (), move ();
  138. return 0;
  139. }

PA2011 pec

PA2011 pod

CF263E Rhombus

维护几个和就完了……

  1. # include <cstdio>
  2. # include <cmath>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  7. # define NR 1010
  8. typedef long long ll;
  9. int b[NR][NR], n, m, K;
  10. ll a[NR][NR], xS[NR][NR], xT[NR][NR], yS[NR][NR], yT[NR][NR], zS[NR][NR];
  11. ll sum[NR][NR], w[NR][NR], pl[NR][NR];
  12. void calc (ll res[NR][NR], bool ty)
  13. {
  14. res[K][K] = pl[K][K] = 0;
  15. REP (i, K) REP (j, K) res[K][K] += a[i][j] * max (0, K - abs (i - K) - abs (j - K)), pl[K][K] += a[i][j] * (K - abs (i - K) - abs (j - K) > 0);
  16. REP (i, n)
  17. {
  18. REP (j, m)
  19. {
  20. xS[i][j] = xS[i][j - 1] + a[i][j];
  21. xT[i][j] = xT[i][j - 1] + a[i][j] * j;
  22. yS[i][j] = yS[i - 1][j] + a[i][j];
  23. yT[i][j] = yT[i - 1][j] + a[i][j] * i;
  24. zS[i][j] = zS[i - 1][j + 1] + a[i][j];
  25. if (K <= i && i <= n - K + 1 && K <= j && j <= m - K + 1)
  26. {
  27. if (j == K)
  28. {
  29. if (i != K)
  30. {
  31. pl[i][K] = pl[i - 1][K] - (zS[i - 1][1] - zS[i - 1 - K][1 + K]) + xS[i][K];
  32. res[i][K] = res[i - 1][K] - pl[i - 1][K] + xT[i][K];
  33. }
  34. }
  35. else
  36. {
  37. pl[i][j] = pl[i][j - 1] - (zS[i][j - K] - zS[i - K][j]) + (yS[i][j] - yS[i - K][j]);
  38. res[i][j] = res[i][j - 1] - pl[i][j - 1] + (yT[i][j] - yT[i - K][j] - (i - K) * (yS[i][j] - yS[i - K][j]));
  39. }
  40. }
  41. }
  42. }
  43. if (ty)
  44. FOR (i, K, n - K + 1)
  45. FOR (j, K, m - K + 1)
  46. res[i][j] -= yT[i][j] - yT[i - K][j] - (i - K) * (yS[i][j] - yS[i - K][j]) +
  47. xT[i][j] - xT[i][j - K] - (j - K) * (xS[i][j] - xS[i][j - K]);
  48. }
  49. int main ()
  50. {
  51. scanf ("%d%d%d", &n, &m, &K);
  52. REP (i, n) REP (j, m) scanf ("%d", &b[i][j]);
  53. REP (i, n) REP (j, m) a[i][j] = b[i][j]; calc (sum, 1); REP (i, n) REP (j, m) w[i][j] += sum[i][j];
  54. REP (i, n) REP (j, m) a[n - i + 1][j] = b[i][j]; calc (sum, 0); REP (i, n) REP (j, m) w[i][j] += sum[n - i + 1][j];
  55. REP (i, n) REP (j, m) a[i][m - j + 1] = b[i][j]; calc (sum, 0); REP (i, n) REP (j, m) w[i][j] += sum[i][m - j + 1];
  56. REP (i, n) REP (j, m) a[n - i + 1][m - j + 1] = b[i][j]; calc (sum, 1); REP (i, n) REP (j, m) w[i][j] += sum[n - i + 1][m - j + 1];
  57. int _x = 0, _y = 0;
  58. FOR (i, K, n - K + 1)
  59. {
  60. FOR (j, K, m - K + 1)
  61. {
  62. w[i][j] += K * b[i][j];
  63. if (w[i][j] >= w[_x][_y]) _x = i, _y = j;
  64. }
  65. }
  66. printf ("%d %d\n", _x, _y);
  67. return 0;
  68. }

10.5 月曜日

CF360D Levko and Sets

随手用原根算两把再容斥就完了……
想到了自己本来想出的傻逼题……

  1. # include <cstdio>
  2. # include <algorithm>
  3. # include <cassert>
  4. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  5. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  6. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  7. # define MOD 1000007
  8. # define T 5000000
  9. # define TR 210
  10. using namespace std;
  11. typedef long long ll;
  12. struct Hash {int p, w, f; inline void set (int _p, int _w, int _f) {p = _p, w = _w, f = _f;}};
  13. struct HashMap
  14. {
  15. Hash h[T + 10];
  16. int hp[MOD], sz;
  17. inline void ins (int p, int w) {h[++ sz].set (p, w, hp[p % MOD]), hp[p % MOD] = sz;}
  18. inline int find (int p) {for (int i = hp[p % MOD]; i; i = h[i].f) if (h[i].p == p) return h[i].w; return -1;}
  19. } ph, fid;
  20. int li[20000], len, n, m, P, g, a[10100], inv_pow;
  21. ll f[20000];
  22. bool vis[20000];
  23. inline int pr (int a, int z) {int s = 1; do {if (z & 1) s = 1ll * s * a % P; a = 1ll * a * a % P;} while (z >>= 1); return s;}
  24. inline bool check () {REP (i, len) if (li[i] < P - 1 && pr (g, li[i]) == 1) return false; return true;}
  25. inline int findG () {for (g = 2; !check (); ++ g) ; return g;}
  26. template <class Z> Z gcx (Z a, Z b) {return !b ? a : gcx (b, a % b);}
  27. inline int logg (int x)
  28. {
  29. int t; if ((t = ph.find (x)) != -1) return t;
  30. REP (i, TR) {x = 1ll * x * inv_pow % P; if ((t = ph.find (x)) != -1) return i * T + t;}
  31. }
  32. void getFac (int n)
  33. {
  34. for (int i = 1; i * i <= n; ++ i)
  35. {
  36. if (n % i) continue;
  37. li[++ len] = i;
  38. if (i * i != n) li[++ len] = n / i;
  39. }
  40. sort (li + 1, li + len + 1);
  41. REP (i, len) fid.ins (li[i], i);
  42. }
  43. inline void init ()
  44. {
  45. getFac (P - 1), findG (); int tp = 1;
  46. REP_0 (i, T) ph.ins (tp, i), tp = 1ll * tp * g % P;
  47. inv_pow = pr (tp, P - 2);
  48. }
  49. int calc ()
  50. {
  51. f[1] = -1;
  52. REP (i, len)
  53. {
  54. if (!vis[i]) continue;
  55. REP_D (j, len) f[fid.find (1ll * li[i] * li[j] / gcx (li[i], li[j]))] -= f[j];
  56. }
  57. f[1] ++;
  58. int res = 0;
  59. REP (i, len) res += f[i] * (P - 1) / li[i];
  60. return res;
  61. }
  62. int main ()
  63. {
  64. scanf ("%d%d%d", &n, &m, &P), init (); int b, tb;
  65. REP (i, n) scanf ("%d", &a[i]), a[i] = logg (a[i]);
  66. scanf ("%d", &b);
  67. REP (i, m - 1) scanf ("%d", &tb), b = gcx (tb, b);
  68. REP (i, n) vis[fid.find (gcx (1ll * a[i] * b, P - 1ll))] = true;
  69. printf ("%d\n", calc ());
  70. return 0;
  71. }

PA2011 prz

我为什么这种题要看题解T_T 真是没救了……
显然放到模意义下一算就完了……

  1. # include <cstdio>
  2. # include <algorithm>
  3. using namespace std;
  4. const int inf = 1 << 30;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define NR 250010
  7. pair <int, int> seg[NR];
  8. int q0, s, k, n, sl;
  9. int main ()
  10. {
  11. for (scanf ("%d", &q0); q0; -- q0)
  12. {
  13. scanf ("%d%d%d", &s, &k, &n); sl = 0;
  14. int p = 0, tL = -1, tR = k, len; bool succ = true;
  15. REP (i, n)
  16. {
  17. scanf ("%d", &len);
  18. if (i & 1)
  19. {
  20. if (len >= k) succ = false;
  21. int pl = p, pr = p + len - 1;
  22. if (pr < k) seg[++ sl] = make_pair (pl, pr);
  23. else tL = max (tL, pr % k), tR = min (tR, pl);
  24. }
  25. p = (p + len) % k;
  26. }
  27. if (!succ) {puts ("NIE"); continue;}
  28. if (tL != -1) seg[++ sl] = make_pair (0, tL);
  29. if (tR != k) seg[++ sl] = make_pair (tR, k - 1);
  30. sort (seg + 1, seg + sl + 1);
  31. int lst = 0; succ = false;
  32. REP (i, sl)
  33. {
  34. if (seg[i].first - lst >= s) {succ = true; break;}
  35. lst = max (lst, seg[i].second + 1);
  36. }
  37. if (k - lst >= s) succ = true;
  38. puts (succ ? "TAK" : "NIE");
  39. }
  40. return 0;
  41. }

TCO2012 Round 1B FoxAndPhotography

显然的状压吧……
表示中当前取了状态为的元素来对应中前个元素。

  1. # include <cstdio>
  2. # include <algorithm>
  3. # include <vector>
  4. # include <cassert>
  5. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  6. const int inf = 1 << 30;
  7. using namespace std;
  8. class FoxAndPhotography
  9. {
  10. private:
  11. int f[1 << 16], n, M;
  12. vector <int> a, b;
  13. int search (int s)
  14. {
  15. if (f[s] != inf) return f[s];
  16. int cnt = 1;
  17. REP_0 (i, n) if (s >> i & 1) ++ cnt;
  18. int index = cnt - 1;
  19. REP_0 (i, n)
  20. if (!(s >> i & 1))
  21. {
  22. ++ index;
  23. if (a[i] < b[cnt - 1]) f[s] = min (f[s], search (s | 1 << i) + abs (index - cnt));
  24. }
  25. if (f[s] == inf) f[s] -= 2;
  26. return f[s];
  27. }
  28. public:
  29. int getMinimumSwaps (vector <int> _a, vector <int> _b)
  30. {
  31. a = _a, b = _b;
  32. n = a.size (), M = 1 << n;
  33. REP_0 (i, M - 1) f[i] = inf;
  34. sort (_a.begin (), _a.end ());
  35. sort (_b.begin (), _b.end ());
  36. REP_0 (i, n) if (_a[i] >= _b[i]) return -1;
  37. return search (0);
  38. }
  39. };

10.6 火曜日

然而打NOIP摸你赛还是象傻逼一样秀智商下限。
被虐的要多惨有多惨。
写一道和BZOJ2393差不多的题发现玄不救非。

10.7 水曜日

前几天太浪了补作业T_T

10.8 木曜日

不想上学了T_T
又开始颓颓颓……

TCO2012 Round 2A EvenPaths

其实知道这题是分段FWT以后就显然的要死了T_T
考虑按照拓扑序把特殊格劈成两段。
为了方便计算强制起点为特殊格子。

暴力枚举前半段的特殊点状态,算出起点到每个前半段特殊点的方案数。
暴力枚举后半段的特殊点状态,算出终点走回每个前半段特殊点的方案数。(前半段的其他特殊点不能走)
(窝一开始居然不会暴力枚举还想着DP以后用子集和卷积……)

然后发现就是FWT了嘛……

乱写一通常数根本不管了T_T

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <vector>
  4. # include <string>
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  7. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  8. # define REP_G(i, n) for (int i = pos[x]; i; i = g[i].frt)
  9. # define RST(a) memset (a, 0, sizeof (a))
  10. using namespace std;
  11. typedef long long ll;
  12. # define NR 100
  13. # define ER 10000
  14. # define MR (1 << 19)
  15. struct Edge {int y, frt; void set (int yr, int fr) {y = yr, frt = fr;}};
  16. # define v g[i].y
  17. class EvenPaths
  18. {
  19. private:
  20. Edge g[ER];
  21. int pos[NR], in[NR], q[NR], un[NR], n, gsz, usz, fir, sec;
  22. ll cntA[MR], cntB[MR], ans;
  23. vector <int> e[NR];
  24. bool del[NR], f[NR];
  25. inline void AE (int x, int y) {g[++ gsz].set (y, pos[x]), pos[x] = gsz, ++ in[y];}
  26. void Topo ()
  27. {
  28. int head = 1, tail = 0, x;
  29. REP (i, n) if (!in[i]) q[++ tail] = i;
  30. while (head <= tail)
  31. {
  32. x = q[head ++];
  33. REP_G (i, x) if (!-- in[v]) q[++ tail] = v;
  34. }
  35. }
  36. int bfsFir (int s)
  37. {
  38. REP (i, n) f[i] = del[i] = 0;
  39. REP_0 (i, fir) del[un[i + 1]] = s >> i & 1;
  40. f[1] = 1;
  41. REP (t, n)
  42. {
  43. int x = q[t]; if (!f[x]) continue;
  44. REP_G (i, x) if (!del[v]) f[v] ^= 1;
  45. }
  46. int res = 0;
  47. REP_0 (i, fir) if (f[un[i + 1]]) res |= 1 << i;
  48. return res;
  49. }
  50. int bfsSec (int s)
  51. {
  52. REP (i, n) f[i] = del[i] = 0;
  53. REP (i, fir) del[un[i]] = true;
  54. REP_0 (i, sec) del[un[i + fir + 1]] = s >> i & 1;
  55. f[2] = 1;
  56. if (del[2]) return 0;
  57. REP_D (t, n)
  58. {
  59. int x = q[t]; if (!f[x]) continue;
  60. REP_G (i, x) if (!del[v]) f[v] ^= 1;
  61. }
  62. int res = 0;
  63. REP_0 (i, fir)
  64. {
  65. int x = un[i + 1]; bool z = 0;
  66. for (int y : e[x]) z ^= f[y];
  67. if (z) res |= 1 << i;
  68. }
  69. return res;
  70. }
  71. void fwt (ll *a, int l, int r, int ty)
  72. {
  73. if (l == r) return ;
  74. int mid = (l + r) >> 1;
  75. fwt (a, l, mid, ty); fwt (a, mid + 1, r, ty);
  76. REP_0 (i, mid - l + 1) a[l + i] += a[mid + 1 + i] * ty;
  77. }
  78. public:
  79. ll theCount (vector <string> maze, string rooms)
  80. {
  81. n = rooms.length ();
  82. REP (i, n) REP (j, n) if (maze[i - 1][j - 1] == 'Y') AE (i, j), e[i].push_back (j);
  83. Topo ();
  84. int cu = 0; bool v1 = false;
  85. REP (i, n)
  86. {
  87. if (q[i] == 1) un[++ usz] = 1, v1 = true;
  88. else if (rooms[q[i] - 1] == '?') v1 ? un[++ usz] = q[i] : ++ cu;
  89. }
  90. if (rooms[0] == '?') ans += 1ll << (usz - 1);
  91. fir = (usz + 1) / 2, sec = usz - fir;
  92. int N = 1, Mf = 1 << (fir - 1), Ms = 1 << sec;
  93. REP_0 (s, Mf) ++ cntA[bfsFir (s << 1)];
  94. RST (pos), gsz = 0;
  95. REP (i, n) REP (j, n) if (maze[i - 1][j - 1] == 'Y') AE (j, i);
  96. REP_0 (s, Ms) ++ cntB[bfsSec (s)];
  97. for (; N <= (Mf << 1) || N <= Ms; N <<= 1) ;
  98. fwt (cntA, 0, N - 1, 1), fwt (cntB, 0, N - 1, 1);
  99. REP_0 (i, N) cntA[i] *= cntB[i];
  100. fwt (cntA, 0, N - 1, -1);
  101. REP_0 (s, N)
  102. {
  103. bool b = 0;
  104. REP_0 (i, fir) if (s >> i & 1) b ^= 1;
  105. if (!b) ans += cntA[s];
  106. }
  107. return ans << cu;
  108. }
  109. };

TCO2012 Round 1C PasswordXPalindrome

一股想把自己骂死的冲动……
傻逼回家种田去……

  1. # include <cstdio>
  2. # include <string>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  6. class PasswordXPalindrome
  7. {
  8. private:
  9. int ap[30][2], apr[30], t[100], z[100], ans, len;
  10. public:
  11. int minSwaps (string s)
  12. {
  13. ans = 0, len = s.length (); int si = -1;
  14. REP_0 (i, 26) ap[i][0] = -1;
  15. REP_0 (i, len) ++ apr[t[i] = s[i] - 'a'];
  16. REP_0 (i, len)
  17. {
  18. if (apr[t[i]] == 1)
  19. {
  20. if (len % 2 == 0) return -1;
  21. if (si == t[i]) return -1;
  22. else if (i != len / 2) swap (t[i], t[len / 2]), ++ ans, si = t[i], -- i;
  23. }
  24. }
  25. REP_0 (i, len)
  26. if (apr[t[i]] == 2)
  27. {
  28. if (ap[t[i]][0] == -1) ap[t[i]][0] = i, z[i] = 0;
  29. else ap[t[i]][1] = i, z[i] = 1;
  30. }
  31. REP_0 (i, len)
  32. {
  33. if (apr[t[i]] != 2) continue;
  34. while (ap[t[i]][z[i]] != len - ap[t[i]][!z[i]] - 1)
  35. {
  36. int j = len - ap[t[i]][!z[i]] - 1;
  37. swap (t[i], t[j]), swap (z[i], z[j]);
  38. ap[t[i]][z[i]] = i;
  39. ap[t[j]][z[j]] = j;
  40. ++ ans;
  41. }
  42. }
  43. return ans;
  44. }
  45. };

10.9 金曜日

颓……

10.10 土曜日

颓……

10.11 日曜日

初赛啦……
瞎写写一个小时就就交了卷回家颓……

10.12 月曜日

deadline快要到了止颓止颓…………QAQ
晚上CF上黄啦www
不过啊……我已经高一了呢……

PA2011 pie

CF585B Phillip and Trains

暴力。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <cmath>
  4. # include <algorithm>
  5. # include <cassert>
  6. # include <iostream>
  7. using namespace std;
  8. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  9. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  10. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  11. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  12. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  13. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  14. # define RST(a) memset (a, 0, sizeof (a))
  15. # define CLR(a, x) memset (a, x, sizeof (a))
  16. # define CPY(a, b) memcpy (a, b, sizeof (a))
  17. typedef long long ll;
  18. typedef long double ld;
  19. const int inf = 1 << 30;
  20. const ll lnf = 1ll << 60;
  21. template <class T0, class T1> bool RlxX (T0 &a, T1 b) {if (a < b) return a = b, true; return false;}
  22. template <class T0, class T1> bool RlxN (T0 &a, T1 b) {if (a > b) return a = b, true; return false;}
  23. int f[4][200][2];
  24. int n, m, q0, sX, sY;
  25. char s[4][200];
  26. bool train (int x, int y) {return s[x][y] <= 'Z' && s[x][y] >= 'A';}
  27. bool dfs (int x, int y, int z)
  28. {
  29. if (y > n) return true;
  30. if (train (x, y)) return false;
  31. if (f[x][y][z] != -1) return f[x][y][z];
  32. if (z)
  33. {
  34. if (train (x, y + 1) || train (x, y + 2)) return f[x][y][z] = false;
  35. return f[x][y][z] = dfs (x, y + 2, 0);
  36. }
  37. else
  38. {
  39. if (train (x, y + 1)) return f[x][y][z] = false;
  40. if (dfs (x, y + 1, 1)) return f[x][y][z] = true;
  41. if (x != 1 && dfs (x - 1, y + 1, 1)) return f[x][y][z] = true;
  42. if (x != 3 && dfs (x + 1, y + 1, 1)) return f[x][y][z] = true;
  43. }
  44. return f[x][y][z] = false;
  45. }
  46. int main ()
  47. {
  48. for (scanf ("%d", &q0); q0; -- q0)
  49. {
  50. scanf ("%d%d", &n, &m);
  51. CLR (f, -1), RST (s);
  52. REP (i, 3)
  53. {
  54. scanf ("%s", s[i] + 1);
  55. REP (j, n) if (s[i][j] == 's') sX = i, sY = j;
  56. }
  57. printf ("%s\n", dfs (sX, sY, 0) ? "YES" : "NO");
  58. }
  59. return 0;
  60. }

CF585C Alice, Bob, Oranges and Apples

每次试图用向量表示出最终向量。
改动的时候重新把最终向量正交分解。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <cmath>
  4. # include <algorithm>
  5. # include <cassert>
  6. # include <iostream>
  7. using namespace std;
  8. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  9. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  10. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  11. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  12. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  13. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  14. # define RST(a) memset (a, 0, sizeof (a))
  15. # define CLR(a, x) memset (a, x, sizeof (a))
  16. # define CPY(a, b) memcpy (a, b, sizeof (a))
  17. typedef long long ll;
  18. typedef long double ld;
  19. const int inf = 1 << 30;
  20. const ll lnf = 1ll << 60;
  21. char tmp[1001000];
  22. string res;
  23. ll a, b;
  24. bool solve (ll a, ll b, char A, char B)
  25. {
  26. if (!a && !b) return true;
  27. if (a == b) return false;
  28. if (a < b) return solve (b, a, B, A);
  29. sprintf (tmp, "%I64d%c", a / (b + 1), A);
  30. res.append (tmp);
  31. return solve (a % (b + 1), b, A, B);
  32. }
  33. int main ()
  34. {
  35. scanf ("%I64d%I64d", &a, &b);
  36. if (solve (a - 1, b - 1, 'A', 'B')) cout << res << endl;
  37. else cout << "Impossible" << endl;
  38. return 0;
  39. }

CF585D Lizard Era: Beginning

分段大暴力。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <cmath>
  4. # include <algorithm>
  5. # include <cassert>
  6. # include <iostream>
  7. # include <map>
  8. using namespace std;
  9. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  10. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  11. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  12. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  13. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  14. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  15. # define RST(a) memset (a, 0, sizeof (a))
  16. # define CLR(a, x) memset (a, x, sizeof (a))
  17. # define CPY(a, b) memcpy (a, b, sizeof (a))
  18. typedef long long ll;
  19. typedef long double ld;
  20. const int inf = 1 << 30;
  21. const ll lnf = 1ll << 60;
  22. template <class T0, class T1> bool RlxX (T0 &a, T1 b) {if (a < b) return a = b, true; return false;}
  23. template <class T0, class T1> bool RlxN (T0 &a, T1 b) {if (a > b) return a = b, true; return false;}
  24. # define NR 50
  25. typedef map <pair <int, int>, pair <int, int> >::iterator Mi;
  26. int n0, n, dx[NR], dy[NR], dz[NR], rec[NR], ans, S0, S1;
  27. map <pair <int, int>, pair <int, int> > vis;
  28. void dfs0 (int i, int x, int y, int z, int mask)
  29. {
  30. if (i > n0)
  31. {
  32. Mi it = vis.find (make_pair (y, z));
  33. if (it == vis.end ()) vis.insert (make_pair (make_pair (y, z), make_pair (x, mask)));
  34. else it->second = max (it->second, make_pair (x, mask));
  35. return ;
  36. }
  37. dfs0 (i + 1, x, y + dy[i], z + dz[i], mask * 3);
  38. dfs0 (i + 1, x + dx[i], y - dx[i], z + dz[i] - dx[i], mask * 3 + 1);
  39. dfs0 (i + 1, x + dx[i], y + dy[i] - dx[i], z - dx[i], mask * 3 + 2);
  40. }
  41. void dfs1 (int i, int x, int y, int z, int mask)
  42. {
  43. if (i > n)
  44. {
  45. if (vis.find (make_pair (-y, -z)) == vis.end ()) return ;
  46. pair <int, int> t = vis[make_pair (-y, -z)];
  47. if (t.first + x > ans) ans = t.first + x, S0 = t.second, S1 = mask;
  48. return ;
  49. }
  50. dfs1 (i + 1, x, y + dy[i], z + dz[i], mask * 3);
  51. dfs1 (i + 1, x + dx[i], y - dx[i], z + dz[i] - dx[i], mask * 3 + 1);
  52. dfs1 (i + 1, x + dx[i], y + dy[i] - dx[i], z - dx[i], mask * 3 + 2);
  53. }
  54. char str[4][4] = {"MW", "LW", "LM"};
  55. int main ()
  56. {
  57. scanf ("%d", &n); n0 = n >> 1; ans = -inf;
  58. REP (i, n) scanf ("%d%d%d", &dx[i], &dy[i], &dz[i]);
  59. dfs0 (1, 0, 0, 0, 0), dfs1 (n0 + 1, 0, 0, 0, 0);
  60. if (ans != -inf)
  61. {
  62. REP_D (i, n0) rec[i] = S0 % 3, S0 /= 3;
  63. DWN (i, n0 + 1, n) rec[i] = S1 % 3, S1 /= 3;
  64. REP (i, n) puts (str[rec[i]]);
  65. }
  66. else puts ("Impossible");
  67. return 0;
  68. }

10.13 火曜日

ASC02 A Non Absorbing DFA

坑了好久的题了……
早上看数据发现高精度输出错了2333

感觉自己使用coach mode的姿势不大对QAQ

把不需要删除字符的边连到从它出发走不需要删除的边遇到的第一条需要删除的边即可。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. # include <iostream>
  5. # include <vector>
  6. # define REP(i, n) for (int i = 1; i <= n; i ++)
  7. # define REP_0(i, n) for (int i = 0; i < n; i ++)
  8. # define REP_D0(i, n) for (int i = n - 1; i >= 0; i --)
  9. # define W 1000000000
  10. using namespace std;
  11. struct BigInteger
  12. {
  13. vector <int> s;
  14. BigInteger () {s.clear ();}
  15. void operator += (BigInteger b)
  16. {
  17. REP_0 (i, b.s.size ())
  18. {
  19. if (i + 1 > s.size ()) s.push_back (b.s[i]);
  20. else s[i] = s[i] + b.s[i];
  21. }
  22. REP_0 (i, s.size ())
  23. if (s[i] >= W)
  24. {
  25. s[i] -= W;
  26. if (i + 2 > s.size ()) s.push_back (1);
  27. else s[i + 1] ++;
  28. }
  29. }
  30. void output ()
  31. {
  32. if (!s.size ()) {puts ("0"); return ;}
  33. char ts[20];
  34. REP_D0 (i, s.size ())
  35. {
  36. if (i + 1 == s.size ()) printf ("%d", s[i]);
  37. else
  38. {
  39. int tl = 0, tmp = s[i];
  40. REP_0 (i, 9) ts[i] = 0;
  41. while (tmp) ts[tl ++] = tmp % 10, tmp /= 10;
  42. REP_D0 (i, 9) printf ("%d", ts[i]);
  43. }
  44. }
  45. puts ("");
  46. }
  47. };
  48. int n, Z, S, K, g[1010][30], stk[1010], top;
  49. bool h[1010][30], vis[1010][30], vT[1010];
  50. BigInteger f[62][1010];
  51. int main ()
  52. {
  53. freopen ("dfa.in", "r", stdin);
  54. freopen ("dfa.out", "w", stdout);
  55. char rts[30]; int tt, lT;
  56. scanf ("%s", rts); Z = strlen (rts);
  57. scanf ("%d%d%d", &n, &S, &lT);
  58. REP (i, lT) scanf ("%d", &tt), vT[tt] = true;
  59. REP (i, n) REP (c, Z) scanf ("%d", &g[i][c]);
  60. REP (i, n) REP (c, Z) scanf ("%d", &h[i][c]);
  61. int abd = n + 1;
  62. REP (c, Z) g[n + 1][c] = n + 1;
  63. REP (i, n)
  64. REP (c, Z)
  65. if (h[i][c])
  66. {
  67. int vi;
  68. for (int u = i; 1; u = g[u][c])
  69. {
  70. vis[stk[++ top] = u][c] = true;
  71. if (!h[u][c]) {vi = g[u][c]; break;}
  72. if (vis[g[u][c]][c]) {vi = abd; break;}
  73. }
  74. while (top)
  75. {
  76. g[stk[top]][c] = vi, h[stk[top]][c] = vis[stk[top]][c] = false;
  77. top --;
  78. }
  79. }
  80. n ++;
  81. scanf ("%d", &K);
  82. f[0][S].s.push_back (1);
  83. REP (k, K) REP (i, n) REP (c, Z) f[k][g[i][c]] += f[k - 1][i];
  84. BigInteger ans;
  85. REP (i, n) if (vT[i]) ans += f[K][i];
  86. ans.output ();
  87. return 0;
  88. }

10.14 水曜日

PA2009 sza

…………简直了……
没有C++11的世界T_T(幸好自己用的一堆STL没T…………
写了好久好久好久T_T
考虑后缀树,唯一问题是匹配开头,匹配其他的可以用平衡树启发式合并。
考虑使用KMP。
考虑每个后缀树节点到其父亲节点的边上的每一个位置到根的路径组成的字符串,令我们当前考虑的边中的可行字符串是,其中是当前后缀树节点的笫一次出现位置。
那么该边的贡献为
该条件的必要性显然,充分性的话,
因为若,则显然不是该后缀节点的第一次出现位置,不可能。
所以写啊写就行了……
另外sort居然会自己和自己比大小T_T(我也不知道stable_sort会不会>_<

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <map>
  4. # include <set>
  5. # include <vector>
  6. using namespace std;
  7. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  8. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  9. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  10. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  11. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  12. # define RST(a) memset (a, 0, sizeof (a))
  13. # define CLR(a, x) memset (a, x, sizeof (a))
  14. typedef set <int>::iterator Si;
  15. typedef map <int, int>::iterator Mi;
  16. typedef long long ll;
  17. const int inf = 1 << 30;
  18. # define u t[x]
  19. # define o t[y]
  20. # define ulfc t[u.lc]
  21. # define urtc t[u.rc]
  22. # define NR 201000
  23. # define SR 401000
  24. struct Seg {int lc, rc, cnt;} t[5010000];
  25. vector <int> e[SR], tp[NR];
  26. struct Sam {int trans[26], par, l, p; bool ed; Sam () {CLR (trans, -1);}} sam[SR];
  27. int next[NR], ro[NR];
  28. int lst, ssz, tsz, n, finL, finE;
  29. ll ans;
  30. map <int, int> al[SR];
  31. set <int> ap[SR];
  32. char s[NR];
  33. int segModi (int l, int r, int p, int y)
  34. {
  35. int x = ++ tsz, mid = (l + r) >> 1; u = o; ++ u.cnt;
  36. if (l == r) return x;
  37. if (p <= mid) u.lc = segModi (l, mid, p, o.lc);
  38. else u.rc = segModi (mid + 1, r, p, o.rc);
  39. return x;
  40. }
  41. int segQry (int x, int l, int r, int ql, int qr)
  42. {
  43. if (!x || l > r) return 0;
  44. if (ql <= l && r <= qr) return u.cnt;
  45. int mid = (l + r) >> 1, ret = 0;
  46. if (ql <= mid) ret += segQry (u.lc, l, mid, ql, qr);
  47. if (qr > mid) ret += segQry (u.rc, mid + 1, r, ql, qr);
  48. return ret;
  49. }
  50. int segMin (int x, int l, int r, int ml, int mr, int y)
  51. {
  52. int mid = (l + r) >> 1;
  53. if (ml <= l && r <= mr)
  54. {
  55. if (u.cnt == o.cnt) return inf;
  56. if (l == r) return l;
  57. if (ulfc.cnt - t[o.lc].cnt) return segMin (u.lc, l, mid, ml, mr, o.lc);
  58. return segMin (u.rc, mid + 1, r, ml, mr, o.rc);
  59. }
  60. int tmp;
  61. if (ml <= mid && (tmp = segMin (u.lc, l, mid, ml, mr, o.lc)) != inf) return tmp;
  62. if (mr > mid && (tmp = segMin (u.rc, mid + 1, r, ml, mr, o.rc)) != inf) return tmp;
  63. return inf;
  64. }
  65. # undef u
  66. # undef o
  67. # define u sam[x]
  68. # define o sam[y]
  69. # define w sam[z]
  70. # define v sam[x].trans[c]
  71. # define vn sam[v]
  72. void extend (int c, int ti)
  73. {
  74. int x = lst, z = ++ ssz; lst = z, w.l = u.l + 1, w.p = ti, w.ed = true;
  75. for (; x != -1 && v == -1; x = u.par) v = z;
  76. if (x == -1) w.par = 1;
  77. else if (u.l + 1 == vn.l) w.par = v;
  78. else
  79. {
  80. int y = ++ ssz, tv = v;
  81. o = vn, o.l = u.l + 1, o.ed = false, vn.par = w.par = y;
  82. for (; x != -1 && v == tv; x = u.par) v = y;
  83. }
  84. }
  85. bool cmpS (int x, int y)
  86. {
  87. int cX = s[u.p + sam[u.par].l], cY = s[o.p + sam[o.par].l];
  88. return cX < cY;
  89. }
  90. # undef v
  91. void calcNext ()
  92. {
  93. int j = 0;
  94. FOR (i, 2, n)
  95. {
  96. while (j > 0 && s[j + 1] != s[i]) j = next[j];
  97. if (s[j + 1] == s[i]) ++ j;
  98. tp[next[i] = j].push_back (i);
  99. }
  100. REP (i, n)
  101. {
  102. ro[i] = ro[i - 1];
  103. for (vector <int>::iterator it = tp[i - 1].begin (); it != tp[i - 1].end (); ++ it)
  104. ro[i] = segModi (1, n, *it, ro[i]);
  105. }
  106. }
  107. void merge (int x, int y)
  108. {
  109. if (ap[x].size () < ap[y].size ()) ap[x].swap (ap[y]), al[x].swap (al[y]);
  110. for (Si it = ap[y].begin (); it != ap[y].end (); ++ it)
  111. {
  112. if (ap[x].find (*it) != ap[x].end ()) continue;
  113. Si p = ap[x].insert (*it).first, prev = p, succ = p;
  114. ++ succ;
  115. if (succ == ap[x].end ())
  116. {
  117. ++ al[x][*it - *(-- prev)];
  118. continue;
  119. }
  120. ++ al[x][*succ - *it];
  121. if (p != ap[x].begin ())
  122. {
  123. -- prev;
  124. Mi t = al[x].find (*succ - *prev);
  125. if (!-- t->second) al[x].erase (t);
  126. ++ al[x][*it - *prev];
  127. }
  128. }
  129. al[y].clear (), ap[y].clear ();
  130. }
  131. # define v *it
  132. int maxL, end;
  133. Mi __it;
  134. void dfsSuf (int x, int el)
  135. {
  136. ap[x].insert (el);
  137. if (u.ed) ap[x].insert (n - u.l + 1), ++ al[x][el - (n - u.l + 1)], el = n - u.l + 1;
  138. for (vector <int>::iterator it = e[x].begin (); it != e[x].end (); ++ it)
  139. dfsSuf (v, el), merge (x, v), u.p = min (u.p, vn.p);
  140. __it = al[x].end (); -- __it;
  141. maxL = __it->first, end = *ap[x].begin () - 1;
  142. if (maxL > u.l) return ;
  143. if (!end)
  144. {
  145. if (maxL < finL) finL = max (maxL, sam[u.par].l + 1), finE = u.p;
  146. ans += u.l - max (maxL, sam[u.par].l + 1) + 1;
  147. return ;
  148. }
  149. else
  150. {
  151. int tl = u.p + max (max (end, maxL), sam[u.par].l + 1) - 1, tr = u.p + u.l - 1, tmp = segMin (ro[n], 1, n, tl, tr, ro[u.p - 1]);
  152. ans += segQry (ro[n], 1, n, tl, tr) - segQry (ro[u.p - 1], 1, n, tl, tr);
  153. if (tmp - u.p + 1 < finL) finL = tmp - u.p + 1, finE = u.p;
  154. }
  155. }
  156. int main ()
  157. {
  158. scanf ("%s", s + 1);
  159. sam[lst = ssz = 1].par = -1, finL = inf;
  160. n = strlen (s + 1);
  161. REP_D (i, n) extend (s[i] - 'a', i);
  162. calcNext ();
  163. DWN (x, 2, ssz) e[sam[x].par].push_back (x);
  164. REP (i, ssz) if (e[i].size () > 1) stable_sort (e[i].begin (), e[i].end (), cmpS);
  165. dfsSuf (1, n + 1);
  166. printf ("%lld\n", ans);
  167. REP (i, finL) putchar (s[finE + i - 1]); putchar ('\n');
  168. return 0;
  169. }

CC AUTHEN

…………啊啊啊自己好蠢T_T

考虑为长度为个多余字符的方案数。
为了不重复算算到前一个相同字符就停。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define REP_0N(i, n) for (int i = 0; i <= n; ++ i)
  7. # define RST(a) memset (a, 0, sizeof (a))
  8. # define P 1009419529
  9. # define NR 11000
  10. int n, K, q0;
  11. char s[NR];
  12. int f[NR][120], sum[NR][120];
  13. int main ()
  14. {
  15. for (scanf ("%d", &q0); q0; -- q0)
  16. {
  17. scanf ("%d%d%s", &n, &K, s + 1);
  18. if (!K) {puts ("0"); continue;}
  19. RST (f), RST (sum);
  20. f[0][0] = sum[0][0] = 1;
  21. REP (i, n + K)
  22. {
  23. int k = 1;
  24. for (; i - k > 0 && s[i - k] != s[i]; ++ k) ;
  25. f[i][0] = sum[i][0] = 1;
  26. int jr = min (i - 1, K);
  27. REP (j, jr)
  28. {
  29. int tl = min (j + 1, k);
  30. f[i][j] = sum[i - 1][j];
  31. if (j - tl >= 0) f[i][j] -= sum[i - tl - 1][j - tl];
  32. if (f[i][j] >= P) f[i][j] -= P;
  33. if (f[i][j] < 0) f[i][j] += P;
  34. }
  35. REP (j, K)
  36. {
  37. sum[i][j] = f[i][j] + sum[i - 1][j - 1];
  38. if (sum[i][j] >= P) sum[i][j] -= P;
  39. }
  40. }
  41. int ans = 0;
  42. REP_0N (i, K)
  43. {
  44. ans += f[n + K - i][K - i];
  45. if (ans >= P) ans -= P;
  46. }
  47. printf ("%d\n", (ans + P - 1) % P);
  48. }
  49. return 0;
  50. }

CC SKIRES

自己状态好差T_T
考虑把一个点高度可能的取值,拆点建图即可。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  7. # define RST(a) memset (a, 0, sizeof (a))
  8. # define CLR(a, x) memset (a, x, sizeof (a))
  9. # define v g[i].y
  10. # define fl g[i].f
  11. # define vfl g[i ^ 1].f
  12. # define NR 60
  13. # define PR 15000
  14. # define ER 200000
  15. template <class T> T abs (T a) {return a >= 0 ? a : -a;}
  16. int dx[] = {0, 0, 0, -1, 1};
  17. int dy[] = {0, -1, 1, 0, 0};
  18. const int inf = 1 << 30;
  19. struct Edge {int y, frt, f; void set (int yr, int fr, int ff) {y = yr, frt = fr, f = ff;}} g[ER];
  20. struct Arr {int x, y; Arr () {x = y = 0;} Arr (int _x, int _y):x(_x), y(_y) {}} li[10];
  21. int q0, n, m, Sx, Sy, Tx, Ty, h[NR][NR], pos[PR], gsz, den[NR][NR][5], S, T, hl[NR][NR], dsz;
  22. int q[PR], lv[PR];
  23. inline bool cmpH (Arr a, Arr b) {return h[a.x][a.y] > h[b.x][b.y];}
  24. bool denote ()
  25. {
  26. int h, t, x;
  27. CLR (lv, -1), lv[q[h = t = 1] = S] = 0;
  28. while (h <= t) {x = q[h ++]; REP_G (i, x) if (fl && lv[v] < 0) lv[q[++ t] = v] = lv[x] + 1;}
  29. return lv[T] > 0;
  30. }
  31. int augment (int x, int f)
  32. {
  33. if (x == T) return f;
  34. int s = 0, ff;
  35. REP_G (i, x) if (fl && f && lv[v] == lv[x] + 1 && (ff = augment (v, min (f, fl))))
  36. fl -= ff, vfl += ff, f -= ff, s += ff;
  37. if (!s) lv[x] = -1;
  38. return s;
  39. }
  40. int maxFlow () {int s = 0; for (; denote (); s += augment (S, inf)) ; return s;}
  41. void AE (int x, int y, int z)
  42. {
  43. g[++ gsz].set (y, pos[x], z), pos[x] = gsz;
  44. g[++ gsz].set (x, pos[y], 0), pos[y] = gsz;
  45. }
  46. int main ()
  47. {
  48. for (scanf ("%d", &q0); q0; -- q0)
  49. {
  50. scanf ("%d%d%d%d%d%d", &n, &m, &Sx, &Sy, &Tx, &Ty);
  51. REP (i, n) REP (j, m) {scanf ("%d", &h[i][j]); hl[i][j] = 0;}
  52. RST (den);
  53. if (h[Sx][Sy] < h[Tx][Ty]) {puts ("0"); continue;}
  54. if (abs (Sx - Tx) + abs (Sy - Ty) == 1) {puts ("-1"); continue;}
  55. dsz = 0, gsz = 1; RST (pos);
  56. REP (i, n) REP (j, m) den[i][j][0] = ++ dsz;
  57. REP (i, n)
  58. REP (j, m)
  59. {
  60. if (i == Tx && j == Ty)
  61. {
  62. REP (d, 4)
  63. {
  64. int _i = i + dx[d], _j = j + dy[d];
  65. if (1 <= _i && _i <= n && 1 <= _j && _j <= m && h[_i][_j] >= h[i][j])
  66. AE (den[_i][_j][0], den[i][j][0], inf);
  67. }
  68. continue;
  69. }
  70. REP (d, 4)
  71. {
  72. int _i = i + dx[d], _j = j + dy[d];
  73. if (1 <= _i && _i <= n && 1 <= _j && _j <= m && h[_i][_j] >= h[i][j])
  74. li[++ hl[i][j]] = Arr (_i, _j);
  75. }
  76. if (!hl[i][j]) continue;
  77. sort (li + 1, li + hl[i][j] + 1, cmpH);
  78. REP (k, hl[i][j])
  79. {
  80. den[i][j][k] = ++ dsz;
  81. AE (den[i][j][k], den[i][j][k - 1], h[li[k].x][li[k].y] + 1 - h[i][j]);
  82. AE (den[li[k].x][li[k].y][0], den[i][j][k], inf);
  83. }
  84. }
  85. S = den[Sx][Sy][0], T = den[Tx][Ty][0];
  86. printf ("%d\n", maxFlow ());
  87. }
  88. return 0;
  89. }

10.15 木曜日

CC E5

啊啊啊感觉自己好弱啊T_T
首先重要结论是若最终序列中有长度不小于3的下降子序列则无解。
原因是注意到,即该式子算的是假若,则对于,否则对于这样的排列
则可以发现可以把数分成两类,存在和不存在的,两类数各自形成一个上升序列。
我们填第二类数,把第一类数的空预留出来。
我们先忽略要求前个数的限制。
为填了个数预留个空,的排列数量。

则转移显然有三种,经过计算可得

考虑前个数的话直接按照这么填就好了。
的那一维可以省略。
大概还可以用前缀和优化转移吧,懒得写了。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  5. # define REP_0N(i, n) for (int i = 0; i <= n; ++ i)
  6. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  7. # define CLR(a, x) memset (a, x, sizeof (a))
  8. # define NR 50
  9. using namespace std;
  10. typedef long long ll;
  11. int n, m, q0, a[NR], p[NR], M;
  12. ll f[NR][NR];
  13. ll dfs (int i, int j)
  14. {
  15. if (j < 0 || j > n) return 0;
  16. if (i > n) return !j;
  17. if (f[i][j] != -1) return f[i][j];
  18. if (p[i] == -1)
  19. {
  20. if (i + j <= m)
  21. {
  22. f[i][j] = 0;
  23. FOR (t, m - (i + j - 1), n) f[i][j] += dfs (i + 1, j + t);
  24. }
  25. else
  26. {
  27. f[i][j] = dfs (i + 1, j);
  28. REP (t, n) f[i][j] += dfs (i + 1, j + t);
  29. if (i > M) f[i][j] += dfs (i + 1, j - 1);
  30. }
  31. }
  32. else
  33. {
  34. if (p[i] == i + j) f[i][j] = dfs (i + 1, j);
  35. else if (p[i] < i + j) f[i][j] = dfs (i + 1, j - 1);
  36. else f[i][j] = dfs (i + 1, j + p[i] - (i + j));
  37. }
  38. return f[i][j];
  39. }
  40. int main ()
  41. {
  42. for (scanf ("%d", &q0); q0; -- q0)
  43. {
  44. scanf ("%d%d", &n, &m), M = 0;
  45. int lst = 0; CLR (f, -1);
  46. int ci = 1; bool valid = true;
  47. REP (i, n) p[i] = -1;
  48. REP (i, m)
  49. {
  50. scanf ("%d", &a[i]), p[a[i]] = i;
  51. if (a[i] == ci) for (++ ci; p[ci] != -1 && ci <= n; ++ ci) ;
  52. else if (a[i] < lst) valid = false;
  53. else lst = a[i];
  54. M = max (a[i], M);
  55. }
  56. if (!valid) {puts ("0"); continue;}
  57. printf ("%lld\n", dfs (1, 0));
  58. }
  59. return 0;
  60. }

10.16 金曜日

啊啊啊颓课件QAQ

10.17 土曜日

啊啊啊学妹好不容易来一次嘛>_<

下午的CF毫无输出,感觉药丸啊……

10.18 日曜日

讲课日……QAQ
被hzt1爷虐飞(意料之中吧。
又感受到了许多完爆标解的做法……
感觉hzt1爷早晚国家队。

10.19 月曜日

CEOI2015 indcyc

太吓人了……
标解400lines什么鬼啊……
题解休息的时候再写好了……

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. # include <vector>
  5. using namespace std;
  6. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  7. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  8. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  9. # define REP_G(i, x) for (int i = p[x].pos; i; i = g[i].frt)
  10. # define NR 1010
  11. const int inf = 1 << 30;
  12. struct Edge {int y, frt; Edge () {y = 0, frt = -1;} Edge (int _y, int _frt): y(_y), frt(_frt) {}};
  13. struct Poi
  14. {
  15. int pos, id, org; bool c;
  16. Poi () {pos = id = org = c = 0;}
  17. Poi (int _pos, int _id, int _org, bool _c): pos(_pos), id(_id), org(_org), c(_c) {}
  18. };
  19. bool e[NR][NR];
  20. int n, m, lo, ln, al, aX, aY, len;
  21. int op[NR], np[NR], dt[NR], pre[NR], ans[NR], match[NR], q[NR], li[NR];
  22. void bfs (int f)
  23. {
  24. int head = 1, tail = 1, u;
  25. REP_0 (i, n) dt[i] = inf;
  26. q[1] = aX, dt[aX] = 1, pre[aX] = -1, dt[f] = -1;
  27. REP_0 (v, n) if (e[f][v] && v != aX && v != aY) dt[v] = -1;
  28. while (head <= tail)
  29. {
  30. u = q[head ++];
  31. REP_0 (v, n) if (e[u][v] && dt[u] + 1 < dt[v]) dt[q[++ tail] = v] = dt[u] + 1, pre[v] = u;
  32. }
  33. for (u = aY; u != -1; u = pre[u]) ans[++ al] = u;
  34. }
  35. # define v g[i].y
  36. class Solver
  37. {
  38. public:
  39. vector <Edge> g;
  40. vector <Poi> p;
  41. int gsz, csz, n;
  42. void AE (int x, int y) {g.push_back (Edge (y, p[x].pos)), p[x].pos = ++ gsz;}
  43. Solver () {gsz = csz = 0, g.clear (), p.clear (), g.push_back (Edge (0, 0));}
  44. Solver (Solver* b, int cid)
  45. {
  46. gsz = csz = n = 0, g.clear (), p.clear (), g.push_back (Edge (0, 0));
  47. REP_0 (i, b->n) if (abs (b->p[i].id) == cid) p.push_back (Poi (0, 0, b->p[i].org, b->p[i].id < 0)), match[i] = n ++;
  48. REP_0 (x, b->n)
  49. if (abs (b->p[x].id) == cid)
  50. for (int i = b->p[x].pos; i; i = b->g[i].frt)
  51. if (abs (b->p[b->g[i].y].id) == cid)
  52. AE (match[x], match[b->g[i].y]);
  53. }
  54. bool solve ()
  55. {
  56. if (n < 4) return false;
  57. int u = 0;
  58. REP_0 (i, n) if (p[i].c) {u = i; break;}
  59. p[u].id = -inf;
  60. REP_G (i, u) p[v].id = -(n + 3);
  61. REP_0 (i, n)
  62. if (!p[i].id)
  63. {
  64. len = 0, color (i, ++ csz);
  65. if (len > 1 && clique (csz)) return bfs (p[u].org), ans[++ al] = p[u].org, true;
  66. if ((new Solver (this, csz))->solve ()) return true;
  67. }
  68. REP_0 (i, n) p[i].id = p[i].id < 0 && p[i].id != -inf;
  69. return (new Solver (this, 1))->solve ();
  70. }
  71. private:
  72. inline bool clique (int c)
  73. {
  74. lo = ln = 0;
  75. REP (i, len) if (p[li[i]].id == -c) p[li[i]].c ? op[++ lo] = p[li[i]].org : np[++ ln] = p[li[i]].org;
  76. REP (i, lo) REP (j, ln) if (!e[op[i]][np[j]]) return aX = op[i], aY = np[j], true;
  77. REP (i, ln) FOR (j, i + 1, ln) if (!e[np[i]][np[j]]) return aX = np[i], aY = np[j], true;
  78. return false;
  79. }
  80. void color (int x, int c)
  81. {
  82. p[x].id = c;
  83. REP_G (i, x)
  84. {
  85. if (!p[v].id) color (v, c);
  86. else if (p[v].id < 0 && p[v].id != -inf && p[v].id != -c) p[li[++ len] = v].id = -c;
  87. }
  88. }
  89. } root;
  90. int main ()
  91. {
  92. scanf ("%d%d", &n, &m); int t1, t2;
  93. REP_0 (i, n) root.p.push_back (Poi (0, 0, i, 0)), ++ root.n;
  94. REP (i, m)
  95. {
  96. scanf ("%d%d", &t1, &t2), -- t1, -- t2;
  97. e[t1][t2] = e[t2][t1] = true, root.AE (t1, t2), root.AE (t2, t1);
  98. }
  99. if (root.solve ()) {REP (i, al) printf ("%d ", ans[i] + 1); puts ("");}
  100. else puts ("no");
  101. return 0;
  102. }

AMPPZ2014 ben

10.20 火曜日

AMPPZ2014 cen

AMMPPZ2014 glo

10.21 水曜日

把前两天做的题当成NOIP摸你赛出了。
说难是什么鬼啊……

AMPPZ2014 fil

AMPPZ2014 ins

10.22 木曜日

BOI2014 sequence

QAQ自己好笨
考虑最后一位,令为当前第个数需要包含的数字的集合。
去掉最后一位后序列是形如
缩起来递归下去。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <cstdlib>
  4. # include <cassert>
  5. # include <iostream>
  6. # include <algorithm>
  7. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  8. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  9. # define NR 101000
  10. using namespace std;
  11. typedef long long ll;
  12. const ll lnf = 1ll << 61;
  13. int a[NR];
  14. # define e(s, i) ((s) >> (i) & 1)
  15. ll c1 (int s)
  16. {
  17. if (s == 1) return 10;
  18. ll f = 0; bool ze = e (s, 0);
  19. REP (i, 9) if (e (s, i)) {f = f * 10 + i; if (ze) f *= 10, ze = false;}
  20. return f;
  21. }
  22. ll c2 (int s0, int s1, bool ty)
  23. {
  24. int _s0 = s0, _s1 = s1; ll f = lnf;
  25. if (s0 == 1 && s1 == 1) return 100;
  26. if (s0 == 1 && !s1) return 10;
  27. if (!s0 && s1 == 0) return 9;
  28. REP_0 (t, 9)
  29. {
  30. if (e (s0, t)) s0 ^= 1 << t;
  31. if (e (s1, t + 1)) s1 ^= 1 << (t + 1);
  32. f = min (f, c1 (s0 | s1) * 10 + t);
  33. s0 = _s0, s1 = _s1;
  34. }
  35. if (ty)
  36. {
  37. if (e (s0, 9)) s0 ^= 1 << 9;
  38. if (e (s1, 0)) s1 ^= 1;
  39. f = min (f, c2 (s0, s1, false) * 10 + 9);
  40. }
  41. return f;
  42. }
  43. struct Solver
  44. {
  45. int *d, n;
  46. Solver () {n = 0, d = NULL;}
  47. Solver (int _n)
  48. {
  49. n = _n;
  50. d = (int*) malloc (n * sizeof (int));
  51. REP_0 (i, n) d[i] = 0;
  52. }
  53. # define w(t, i) (d[t] >> (i) & 1)
  54. ll solve ()
  55. {
  56. if (n == 1) return c1 (d[0]);
  57. if (n == 2) return c2 (d[0], d[1], true);
  58. bool succ = true;
  59. REP_0 (i, n) if (d[i]) succ = false;
  60. if (succ) return 0;
  61. ll res = lnf;
  62. REP_0 (f, 10)
  63. {
  64. int cur = f, sz = 0;
  65. Solver *next = new Solver ((n + f + 9) / 10);
  66. REP_0 (i, n)
  67. {
  68. if (w (i, cur)) next->d[sz] |= d[i] ^ 1 << cur;
  69. else next->d[sz] |= d[i];
  70. ++ cur;
  71. if (cur == 10 && i + 1 != n) cur = 0, ++ sz;
  72. }
  73. res = min (res, next->solve () * 10 + f); delete next;
  74. }
  75. return res;
  76. }
  77. };
  78. int main ()
  79. {
  80. int n, t1; scanf ("%d", &n);
  81. Solver *sol = new Solver (n);
  82. REP_0 (i, n) scanf ("%d", &t1), sol->d[i] |= 1 << t1;
  83. printf ("%lld\n", sol->solve ());
  84. return 0;
  85. }

10.23 金曜日

AMPPZ2014 hit

10.24 土曜日

PA2011 bwp

PA2011 kan

10.25 日曜日

这场CF好逗啊……
可惜还是打错一个减号没A掉D T_T
不过想来自己只是想和BF打CF呢。结果什么的嘛。

PA2011 aut

CF590A Median Smoothing

直接模拟。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  7. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  8. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  9. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  10. # define RST(a) memset (a, 0, sizeof (a))
  11. # define CLR(a, x) memset (a, x, sizeof (a))
  12. # define NR 501000
  13. # define w0 first
  14. # define w1 second
  15. int n, a[NR], len, ans;
  16. pair <int, int> li[NR];
  17. int main ()
  18. {
  19. scanf ("%d", &n);
  20. REP (i, n) scanf ("%d", &a[i]);
  21. a[0] = a[1], a[n + 1] = a[n];
  22. int last = a[1], ti = 2;
  23. li[++ len] = make_pair (1, 1);
  24. FOR (i, 2, n + 1)
  25. {
  26. if (a[i] == last)
  27. {
  28. ++ ti;
  29. if (li[len].w1 != i - 1 && ti >= 2)
  30. li[++ len] = make_pair (i - ti + 1, i);
  31. else if (ti > 2) li[len].w1 ++;
  32. }
  33. else ti = 1, last = a[i];
  34. }
  35. REP (i, len - 1)
  36. {
  37. if (a[li[i].w0] == a[li[i + 1].w0])
  38. {
  39. FOR (j, li[i].w1 + 1, li[i + 1].w0 - 1) a[j] = a[li[i].w0];
  40. ans = max (ans, (li[i + 1].w0 - li[i].w1) >> 1);
  41. }
  42. else
  43. {
  44. int t = (li[i + 1].w0 - li[i].w1 - 1) >> 1;
  45. FOR (j, li[i].w1 + 1, li[i + 1].w0 - 1)
  46. {
  47. if (j - li[i].w1 > t) a[j] = a[li[i + 1].w0];
  48. else a[j] = a[li[i].w0];
  49. }
  50. ans = max (ans, t);
  51. }
  52. }
  53. printf ("%d\n", ans);
  54. REP (i, n) printf ("%d ", a[i]); puts ("");
  55. return 0;
  56. }

CF590C Three States

BFS一遍。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  7. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  8. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  9. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  10. # define RST(a) memset (a, 0, sizeof (a))
  11. # define CLR(a, x) memset (a, x, sizeof (a))
  12. const int inf = 1 << 28;
  13. # define NR 1010
  14. # define SR 1010000
  15. struct pii {int x, y; pii () {x = y = 0;} pii (int _x, int _y): x(_x), y(_y) {}} q[SR];
  16. char s[NR][NR];
  17. int dc[NR][NR], dt[4][NR][NR], n, m;
  18. int dx[] = {0, 0, -1, 1};
  19. int dy[] = {-1, 1, 0, 0};
  20. bool valid (int x, int y) {return x >= 1 && x <= n && y >= 1 && y <= m && s[x][y] != '#';}
  21. int main ()
  22. {
  23. scanf ("%d%d", &n, &m); int ans;
  24. REP (i, n) scanf ("%s", s[i] + 1);
  25. REP (i, 3) REP (j, 3) if (i != j) dc[i][j] = inf;
  26. REP (id, 3)
  27. {
  28. int head = 1, tail = 0;
  29. REP (i, n) REP (j, m) if (s[i][j] == '0' + id) q[++ tail] = pii (i, j); else dt[id][i][j] = inf;
  30. while (head <= tail)
  31. {
  32. pii u = q[head ++];
  33. if (s[u.x][u.y] >= '0' && s[u.x][u.y] <= '9')
  34. {
  35. int td = s[u.x][u.y] - '0';
  36. dc[id][td] = min (dc[id][td], dt[id][u.x][u.y]);
  37. }
  38. REP_0 (d, 4)
  39. {
  40. int _x = u.x + dx[d], _y = u.y + dy[d];
  41. if (valid (_x, _y) && dt[id][_x][_y] == inf) q[++ tail] = pii (_x, _y), dt[id][_x][_y] = dt[id][u.x][u.y] + 1;
  42. }
  43. }
  44. }
  45. ans = min (dc[1][2] + dc[1][3], min (dc[2][1] + dc[2][3], dc[3][1] + dc[3][2])) - 2;
  46. REP (i, n) REP (j, m) ans = min (ans, dt[1][i][j] + dt[2][i][j] + dt[3][i][j] - 2);
  47. printf ("%d\n", ans > n * m ? -1 : ans);
  48. return 0;
  49. }

CF590D Top Secret Task

显然是选前K个中的某些数和后面的某些数交换。
确定了交换哪些数以后交换策略是每次交换最里面的一对。
为前K个中选到第个,后面的选到第个剩余交换次数为的答案。

  1. # include <cstdio>
  2. # include <cstring>
  3. # include <algorithm>
  4. using namespace std;
  5. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  6. # define REP_0(i, n) for (int i = 0; i < n; ++ i)
  7. # define REP_D(i, n) for (int i = n; i >= 1; -- i)
  8. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  9. # define DWN(i, a, b) for (int i = b; i >= a; -- i)
  10. # define RST(a) memset (a, 0, sizeof (a))
  11. # define CLR(a, x) memset (a, x, sizeof (a))
  12. int f[2][180][25000], n, K, T, a[200];
  13. const int inf = 1 << 30;
  14. inline void RlxN (int &x, int y) {if (x > y) x = y;}
  15. int main ()
  16. {
  17. scanf ("%d%d%d", &n, &K, &T);
  18. REP (i, n) scanf ("%d", &a[i]);
  19. if (T >= n * n / 2)
  20. {
  21. sort (a + 1, a + n + 1);
  22. int sum = 0;
  23. REP (i, K) sum += a[i];
  24. printf ("%d\n", sum);
  25. return 0;
  26. }
  27. int ans = inf;
  28. CLR (f[0], 60);
  29. FOR (j, K, n) f[0][j][T] = 0;
  30. REP (i, K)
  31. {
  32. bool d = i % 2; CLR (f[d], 60);
  33. FOR (j, K, n)
  34. {
  35. REP_0 (k, T + 1)
  36. {
  37. RlxN (f[d][j][k], f[!d][j][k] + a[i]);
  38. if (k < T) RlxN (f[d][j][k], f[d][j][k + 1]);
  39. if (j > K) RlxN (f[d][j][k], f[d][j - 1][k]);
  40. if (j != K && k + j - i <= T) RlxN (f[d][j][k], f[!d][j - 1][k + j - i] + a[j]);
  41. if (i == K) RlxN (ans, f[d][j][k]);
  42. }
  43. }
  44. }
  45. printf ("%d\n", ans);
  46. return 0;
  47. }

10.26 水曜日

最近越来越喜欢爆OJ了T_T
完全不在状态要拯救一下才行呢……

PA2011 cia

10.17 火曜日

USACO JAN09 Safe Travel

……有并查集做法。挺显然的也。
写的是带标记可并堆,记录子树中的点连出去的边到达的点。

  1. # include <cstdio>
  2. # include <algorithm>
  3. # include <vector>
  4. # include <iostream>
  5. # include <queue>
  6. using namespace std;
  7. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  8. # define REP_G(i, x) for (int i = pos[x]; i; i = g[i].frt)
  9. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  10. # define NR 101000
  11. # define ER 401000
  12. const int inf = 1 << 30;
  13. typedef pair <int, int> pii;
  14. struct Heap {int ch[2], tag, w, id; inline void add (int d) {w += d, tag += d;}} t[ER];
  15. struct Edge {int y, frt, w; void set (int yr, int fr, int wr) {y = yr, frt = fr, w = wr;}} g[ER];
  16. int n, m, gsz, dsz, tsz, pos[NR], dt[NR], ro[NR], pre[NR], bg[NR], ed[NR], ans[NR], pw[NR];
  17. bool vis[NR];
  18. vector <pii> e[NR];
  19. priority_queue <pii> Q;
  20. # define u t[x]
  21. # define lc ch[0]
  22. # define rc ch[1]
  23. # define v g[i].y
  24. inline void AE (int x, int y, int z) {g[++ gsz].set (y, pos[x], z), pos[x] = gsz;}
  25. inline void PD (int x) {if (!u.tag) return ; t[u.lc].add (u.tag), t[u.rc].add (u.tag), u.tag = 0;}
  26. inline int merge (int x, int y)
  27. {
  28. if (!x || !y) return x + y;
  29. if (u.w > t[y].w) swap (x, y);
  30. bool z = rand () & 1; return PD (x), u.ch[z] = merge (u.ch[z], y), x;
  31. }
  32. void dijkstra ()
  33. {
  34. Q.push (pii (0, 1));
  35. FOR (i, 2, n) dt[i] = inf;
  36. while (!Q.empty ())
  37. {
  38. int x = Q.top ().second; Q.pop ();
  39. if (vis[x]) continue; vis[x] = true;
  40. REP_G (i, x)
  41. if (dt[v] > dt[x] + g[i].w)
  42. {
  43. pre[v] = x, pw[v] = g[i].w;
  44. Q.push (pii (-(dt[v] = dt[x] + g[i].w), v));
  45. }
  46. }
  47. }
  48. inline bool in (int y, int x) {return bg[y] && bg[x] <= bg[y] && bg[y] <= ed[x];}
  49. void dfs (int x)
  50. {
  51. bg[x] = ++ dsz;
  52. REP_G (i, x) dfs (v), t[ro[v]].add (g[i].w), ro[x] = merge (ro[x], ro[v]);
  53. ed[x] = dsz;
  54. for (vector <pii>::iterator it = e[x].begin (); it != e[x].end (); ++ it)
  55. if (!in (it->first, x) && it->first != pre[x])
  56. t[++ tsz].w = it->second + dt[it->first], t[tsz].id = it->first, ro[x] = merge (ro[x], tsz);
  57. while (ro[x] && in (t[ro[x]].id, x)) PD (ro[x]), ro[x] = merge (t[ro[x]].lc, t[ro[x]].rc);
  58. ans[x] = ro[x] ? t[ro[x]].w : -1;
  59. }
  60. int main ()
  61. {
  62. srand (1214), scanf ("%d%d", &n, &m); int t1, t2, t3;
  63. REP (i, m) scanf ("%d%d%d", &t1, &t2, &t3), AE (t1, t2, t3), AE (t2, t1, t3), e[t1].push_back (pii (t2, t3)), e[t2].push_back (pii (t1, t3));
  64. dijkstra (), gsz = 0; REP (i, n) pos[i] = 0;
  65. FOR (i, 2, n) {if (dt[i] == inf) ans[i] = -1; else AE (pre[i], i, pw[i]);}
  66. dfs (1);
  67. FOR (i, 2, n) printf ("%d\n", ans[i]);
  68. return 0;
  69. }

PA2011 wyb

SRM533 L3 Pikachu

挺显然的DP吧……
一个类似哈夫曼树的结构,按照到根的长度分层考虑。
考虑为还剩后个数要填,最后三层的可用节点数分别是的答案。
暴力枚举选多少个即可。

  1. # include <cstdio>
  2. # include <algorithm>
  3. # include <vector>
  4. using namespace std;
  5. typedef pair <int, int> pii;
  6. # define REP(i, n) for (int i = 1; i <= n; ++ i)
  7. # define FOR(i, a, b) for (int i = a; i <= b; ++ i)
  8. # define NR 33
  9. # define TR 210
  10. # define w0 first
  11. # define w1 second
  12. # define P 1000000009
  13. const int inf = 1 << 30;
  14. class Pikachu
  15. {
  16. private:
  17. int sum[NR], bi[TR][TR], fac[TR], pre[NR], suc[NR], n;
  18. pii f[NR][NR][NR][NR];
  19. inline void relax (pii &x, pii y)
  20. {
  21. if (y.w0 < x.w0) x.w0 = y.w0, x.w1 = y.w1;
  22. else if (y.w0 == x.w0) {x.w1 += y.w1; if (x.w1 >= P) x.w1 -= P;}
  23. }
  24. pii dfs (int cur, int l0, int l1, int l2)
  25. {
  26. int l3 = l0 + 2 * l1;
  27. if (l3 >= cur) return pii (sum[cur], 1ll * bi[l3][cur] * fac[cur] % P);
  28. pii &w = f[cur][l0][l1][l2];
  29. if (w.w0) return w;
  30. w.w0 = inf;
  31. pii z = dfs (cur, l1, l2, l3);
  32. z.w0 += sum[cur], w = z;
  33. REP (i, l3)
  34. {
  35. int p = cur - i + 1;
  36. pii t = dfs (cur - i, l1, l2, l3 - i);
  37. t.w0 += sum[cur], t.w1 = 1ll * t.w1 * bi[l3][i] % P * bi[min (suc[p], cur) - pre[p] + 1][min (suc[p], cur) - p + 1] % P * fac[i] % P;
  38. relax (w, t);
  39. }
  40. return w;
  41. }
  42. public:
  43. vector <int> bestEncoding (vector <int> a)
  44. {
  45. n = a.size (), sort (a.begin (), a.end ());
  46. bi[0][0] = fac[0] = 1; a.push_back (-1);
  47. int N = 4 * n, last = 1;
  48. REP (i, N)
  49. {
  50. bi[i][0] = 1, fac[i] = 1ll * fac[i - 1] * i % P;
  51. REP (j, i)
  52. {
  53. bi[i][j] = bi[i - 1][j] + bi[i - 1][j - 1];
  54. if (bi[i][j] >= P) bi[i][j] -= P;
  55. }
  56. }
  57. REP (i, n)
  58. {
  59. sum[i] = sum[i - 1] + a[i - 1], pre[i] = last;
  60. if (a[i - 1] != a[i]) {FOR (j, last, i) suc[j] = i; last = i + 1;}
  61. }
  62. pii res = dfs (n, 0, 0, 1);
  63. return {res.w0, res.w1};
  64. }
  65. };
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注