[关闭]
@Falsyta 2015-08-10T02:58:23.000000Z 字数 5880 阅读 1197

mxh带窝打多校之Contest 4

OI mxh带窝飞


约定

题意

1006 Test for Rikka

对于给定的K,请构造N,MN×N01矩阵A,使得(AM)1,N=K

1007 Undirected Graph

给出一个无向图G={V,E},每次询问给出l,r,询问若只保留端点都在[l,r]内的边,图中有多少个连通块。

1012 ZZX and Permutations

给定一个置换p的一种表示a,求字典序最大的原置换。

题解

1006 Test for Rikka

按照01矩阵来做显然是十分苦难的,不妨以图的邻接矩阵来考虑问题。
问题转化成构造一个N,M与无重边有向图G={V,E}使得节点1到节点NM步的方案数为K

我们考虑完全图(含自环)有非常适合本题的性质:c个点的完全图上任意一点走i步的方案数是ci
我们在完全图下准备一条链一直连到终点,这样我们可以控制可以i步走到终点的点数。

c=10就可以在限制内构造出来了。

  1. # include <cstdio>
  2. # define REP(i, n) for (int i = 1; i <= n; i ++)
  3. bool g[100][100];
  4. int q0, a[100];
  5. long long K;
  6. int main ()
  7. {
  8. for (scanf ("%d", &q0); q0; q0 --)
  9. {
  10. scanf ("%I64d", &K);
  11. if (!K) {printf ("1 1\n0\n"); continue;}
  12. int len = 0;
  13. while (K) a[++ len] = K % 10, K /= 10;
  14. int n = 10 + len + 1, m = len + 2;
  15. REP (i, n) REP (j, n) g[i][j] = (i <= 10 && j <= 10);
  16. REP (i, len) {REP (j, a[i]) g[j][10 + i] = 1; g[10 + i][11 + i] = 1;}
  17. printf ("%d %d\n", n, m);
  18. REP (i, n) {REP (j, n) putchar ('0' + g[i][j]); putchar ('\n');}
  19. }
  20. return 0;
  21. }

1007 Undirected Graph

……很老旧的LCT思路…………
令每条边为(x,y)(x<y)
考虑扫描线,每加一条边,替换掉环上x最小的边。
在线段树上更新答案即可。
时间复杂度O(NlogN)

  1. # include <cstdio>
  2. # include <iostream>
  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. using namespace std;
  8. const int NR = 401000;
  9. # define u t[x]
  10. # define o t[y]
  11. # define lc ch[0]
  12. # define rc ch[1]
  13. # define tc ch[ty]
  14. # define vc ch[!ty]
  15. # define ulfc t[u.lc]
  16. # define urtc t[u.rc]
  17. struct Lct {int ch[2], par, min, val; bool rev; void Rev () {rev ^= 1, swap (lc, rc);} void Set (int q) {min = val = q;}} t[NR];
  18. struct Arr {int l, r, id;} q[NR], g[NR];
  19. int n, m, q0, den[NR], ans[NR], dsz;
  20. bool Cmp (Arr a, Arr b) {if (a.r != b.r) return a.r < b.r; return a.l < b.l;}
  21. namespace Se
  22. {
  23. struct Seg {int ch[2], tag; inline void Add (int d) {tag += d;}} t[NR << 2];
  24. int sz;
  25. inline void PD (int x) {if (!x || !u.tag) return ; ulfc.Add (u.tag), urtc.Add (u.tag), u.tag = 0;}
  26. void Build (int x, int l, int r)
  27. {
  28. u.tag = 0;
  29. if (l == r) return ;
  30. int mid = (l + r) >> 1;
  31. Build (u.lc = ++ sz, l, mid), Build (u.rc = ++ sz, mid + 1, r);
  32. }
  33. void SegInc (int x, int l, int r, int il, int ir)
  34. {
  35. if (il <= l && r <= ir) {u.Add (1); return ;}
  36. PD (x); int mid = (l + r) >> 1;
  37. if (il <= mid) SegInc (u.lc, l, mid, il, ir);
  38. if (ir > mid) SegInc (u.rc, mid + 1, r, il, ir);
  39. }
  40. int SegVal (int x, int l, int r, int p)
  41. {
  42. if (l == r) return u.tag;
  43. PD (x); int mid = (l + r) >> 1;
  44. if (p <= mid) return SegVal (u.lc, l, mid, p);
  45. return SegVal (u.rc, mid + 1, r, p);
  46. }
  47. inline void Inc (int l, int r) {SegInc (1, 1, n, l, r);}
  48. inline int Val (int p) {return SegVal (1, 1, n, p);}
  49. }
  50. # define p u.par
  51. inline void PD (int x)
  52. {
  53. if (!x || !u.rev) return ;
  54. if (u.lc) ulfc.Rev (); if (u.rc) urtc.Rev (); u.rev = 0;
  55. }
  56. inline void Upd (int x)
  57. {
  58. u.min = u.val;
  59. if (g[ulfc.min].l < g[u.min].l) u.min = ulfc.min;
  60. if (g[urtc.min].l < g[u.min].l) u.min = urtc.min;
  61. }
  62. inline int sgn (int x) {return t[p].rc == x ? 1 : t[p].lc == x ? 0 : -1;}
  63. inline void sc (int x, int y, bool ty) {u.tc = y, o.par = x;}
  64. inline void Fix (int x) {if (~ sgn (x)) Fix (p); PD (x);}
  65. inline void Rot (int x, bool ty)
  66. {
  67. int y = p, z = o.par;
  68. if (~ sgn (y)) sc (z, x, sgn (y)); else p = z;
  69. sc (y, u.vc, ty), sc (x, y, !ty), Upd (y), Upd (x);
  70. }
  71. int Splay (int x)
  72. {
  73. Fix (x); int t0, t1, y;
  74. while (~ (t0 = sgn (x)))
  75. {
  76. if (~ (t1 = sgn (y = p))) Rot (t0 ^ t1 ? x : y, t0), Rot (x, t1);
  77. else Rot (x, t0);
  78. }
  79. return Upd (x), x;
  80. }
  81. inline int Acs (int tx) {for (int x = tx, y = 0; x; Upd (y = x), x = p) Splay (x), u.rc = y; return Splay (tx);}
  82. # define us t[Acs (x)]
  83. inline int gf (int x) {for (Acs (x); PD (x), u.lc; x = u.lc); return x;}
  84. inline void Evt (int x) {us.Rev ();}
  85. inline void Link (int x, int y) {Evt (x), p = y;}
  86. inline void Cut (int x) {t[us.lc].par = 0, u.lc = 0;}
  87. inline void Cut (int x, int y) {Evt (x), Cut (y);}
  88. inline int Min (int x, int y) {return Evt (y), us.min;}
  89. int main ()
  90. {
  91. g[0].l = 1 << 30;
  92. while (scanf ("%d%d%d", &n, &m, &q0) != EOF)
  93. {
  94. Se::Build (Se::sz = 1, 1, n);
  95. dsz = n;
  96. REP_0N (x, n + m) u.lc = u.rc = u.par = u.rev = u.val = u.min = 0;
  97. REP (i, m)
  98. {
  99. scanf ("%d%d", &g[i].l, &g[i].r);
  100. if (g[i].l > g[i].r) swap (g[i].l, g[i].r);
  101. }
  102. REP (i, q0) scanf ("%d%d", &q[i].l, &q[i].r), q[i].id = i;
  103. sort (g + 1, g + m + 1, Cmp);
  104. sort (q + 1, q + q0 + 1, Cmp);
  105. int qi = 1; g[m + 1].r = g[0].r = -1;
  106. REP (i, m)
  107. {
  108. if (g[i].r != g[i - 1].r)
  109. while (qi <= q0 && q[qi].r < g[i].r)
  110. ans[q[qi].id] = n - Se::Val (q[qi].l), qi ++;
  111. if (gf (g[i].l) != gf (g[i].r))
  112. {
  113. t[den[i] = ++ dsz].Set (i), Link (den[i], g[i].l), Link (den[i], g[i].r);
  114. Se::Inc (1, g[i].l);
  115. }
  116. else
  117. {
  118. int d = Min (g[i].l, g[i].r);
  119. if (g[d].l < g[i].l)
  120. {
  121. den[i] = den[d];
  122. Cut (den[d], g[d].l), Cut (den[d], g[d].r);
  123. t[den[i]].Set (i);
  124. Link (den[i], g[i].l), Link (den[i], g[i].r);
  125. Se::Inc (g[d].l + 1, g[i].l);
  126. }
  127. }
  128. }
  129. while (qi <= q0) ans[q[qi].id] = n - Se::Val (q[qi].l), qi ++;
  130. REP (i, q0) printf ("%d\n", ans[i]);
  131. }
  132. return 0;
  133. }

1012 ZZX and Permutations

考虑贪心地定原置换p每一个位置的值。
位置i在环中的下一个元素即为pi
有两种情况,i是环的最后一个元素或其他元素。
若是最后一个元素,那么第一个值应该在前面。
否则应该是在a中的下一个元素。
注意到环不能嵌套后用线段树与set维护即可。

  1. # include <cstdio>
  2. # include <iostream>
  3. # include <algorithm>
  4. # include <map>
  5. using namespace std;
  6. # define REP(i, n) for (int i = 1; i <= n; i ++)
  7. const int NR = 100100;
  8. # define u t[x]
  9. # define lc ch[0]
  10. # define rc ch[1]
  11. # define ulfc t[u.lc]
  12. # define urtc t[u.rc]
  13. struct Seg {int ch[2], max; bool cov;} t[NR << 2];
  14. map <int, int> pos;
  15. int n, a[NR], tp[NR], sz, q0, fa[NR];
  16. int gf (int x) {return fa[x] == x ? x : (fa[x] = gf (fa[x]));}
  17. inline void Upd (int x)
  18. {
  19. u.max = 0;
  20. if (a[ulfc.max] > a[u.max]) u.max = ulfc.max;
  21. if (a[urtc.max] > a[u.max]) u.max = urtc.max;
  22. }
  23. int Max (int x, int l, int r, int ql, int qr)
  24. {
  25. if (u.cov) return 0;
  26. if (ql <= l && r <= qr) return u.max;
  27. int mid = (l + r) >> 1, ret = 0, tmp;
  28. if (ql <= mid && a[tmp = Max (u.lc, l, mid, ql, qr)] > a[ret]) ret = tmp;
  29. if (qr > mid && a[tmp = Max (u.rc, mid + 1, r, ql, qr)] > a[ret]) ret = tmp;
  30. return ret;
  31. }
  32. void Del (int x, int l, int r, int cl, int cr)
  33. {
  34. if (u.cov) return ;
  35. if (cl <= l && r <= cr) {u.cov = 1, u.max = 0; return ;}
  36. int mid = (l + r) >> 1, ret = 0;
  37. if (cl <= mid) Del (u.lc, l, mid, cl, cr);
  38. if (cr > mid) Del (u.rc, mid + 1, r, cl, cr);
  39. Upd (x);
  40. }
  41. int Build (int l, int r)
  42. {
  43. int x = ++ sz, mid = (l + r) >> 1; u.cov = 0;
  44. if (l == r) return u.max = l, x;
  45. return u.lc = Build (l, mid), u.rc = Build (mid + 1, r), Upd (x), x;
  46. }
  47. bool Cmp (int i, int j) {return a[i] < a[j];}
  48. int main ()
  49. {
  50. for (scanf ("%d", &q0); q0; q0 --)
  51. {
  52. scanf ("%d", &n), sz = 0;
  53. REP (i, n) scanf ("%d", &a[i]), tp[i] = i, fa[i] = 0;
  54. sort (tp + 1, tp + n + 1, Cmp), Build (1, n);
  55. pos.clear (), pos[0] = 0;
  56. REP (p, n)
  57. {
  58. int i = tp[p];
  59. map <int, int>::iterator it = pos.upper_bound (i); it --;
  60. char sc = (p == n ? '\n' : ' ');
  61. if (it->first<it->second)
  62. {
  63. printf ("%d%c", a[i + 1], sc);
  64. continue;
  65. }
  66. if (fa[i])
  67. {
  68. int j = gf (i);
  69. if (i == n || pos.find (i + 1) != pos.end () || a[j] > a[i + 1])
  70. printf ("%d%c", a[j], sc), pos[i] = j, pos[j] = i;
  71. else
  72. Del (1, 1, n, i + 1, i + 1), fa[i + 1] = i, printf ("%d%c", a[i + 1], sc);
  73. continue;
  74. }
  75. int j = Max (1, 1, n, it->first + 1, i);
  76. if (i == n || pos.find (i + 1) != pos.end () || a[j] > a[i + 1])
  77. Del (1, 1, n, j, i), pos[i] = j, pos[j] = i, printf ("%d%c", a[j], sc);
  78. else Del (1, 1, n, i, i + 1), fa[i] = i, fa[i + 1] = i, printf ("%d%c", a[i + 1], sc);
  79. }
  80. }
  81. return 0;
  82. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注