比赛链接:传送门

跌跌撞撞6题摸银。

封榜后两题,把手上的题做完了还算舒服。就是罚时有点高。

开出了一道奇奇怪怪的题(K),然后ccpcf银应该比区域赛银要难吧,反正很开心qwq。


Problem A. Mischievous Problem Setter 00:14 (-2) Solved by Dancepted

良心签到题。WA2吃乳猪。

代码:

  1. #include <iostream>
  2. #include <cmath>
  3. #include <map>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <set>
  8. #include <vector>
  9. #include <string>
  10. #include <queue>
  11. #include <stack>
  12. #include <iomanip>
  13. #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
  14. #define N 100005
  15. #define M 100005
  16. #define INF 0x3f3f3f3f
  17. #define mk(x) (1<<x) // be conscious if mask x exceeds int
  18. #define sz(x) ((int)x.size())
  19. #define upperdiv(a,b) (a/b + (a%b>0))
  20. #define mp(a,b) make_pair(a, b)
  21. #define endl '\n'
  22. #define lowbit(x) (x&-x)
  23.  
  24. using namespace std;
  25. typedef long long ll;
  26. typedef double db;
  27.  
  28. /** fast read **/
  29. template <typename T>
  30. inline void read(T &x) {
  31. x = ; T fg = ; char ch = getchar();
  32. while (!isdigit(ch)) {
  33. if (ch == '-') fg = -;
  34. ch = getchar();
  35. }
  36. while (isdigit(ch)) x = x*+ch-'', ch = getchar();
  37. x = fg * x;
  38. }
  39. template <typename T, typename... Args>
  40. inline void read(T &x, Args &... args) { read(x), read(args...); }
  41. template <typename T>
  42. inline void write(T x) {
  43. int len = ; char c[]; if (x < ) putchar('-'), x = -x;
  44. do{++len; c[len] = x% + '';} while (x /= );
  45. for (int i = len; i >= ; i--) putchar(c[i]);
  46. }
  47. template <typename T, typename... Args>
  48. inline void write(T x, Args ... args) { write(x), write(args...); }
  49.  
  50. struct Node{
  51. int d, t;
  52. bool operator < (const Node& x) const {
  53. return d < x.d;
  54. }
  55. }nodes[N];
  56. int main() {
  57. fast;
  58. int T; cin >> T;
  59. for (int kase = ; kase <= T; kase++) {
  60. int n, m; cin >> n >> m;
  61. for (int i = ; i <= n; i++) {
  62. cin >> nodes[i].d;
  63. }
  64. for (int i = ; i <= n; i++) {
  65. cin >> nodes[i].t;
  66. }
  67. sort(nodes+, nodes++n);
  68. int ans = ;
  69. for (int i = ; i <= n; i++) {
  70. if (nodes[i].t <= m) {
  71. m -= nodes[i].t;
  72. ans++;
  73. }
  74. else {
  75. break;
  76. }
  77. }
  78. cout << "Case " << kase << ": " << ans << endl;
  79. }
  80. return ;
  81. }

Problem L. Ultra Weak Goldbach's Conjecture  00:47(+) Solved by xk (miller rabin + 素数密度 + 哥德巴赫猜想)

根据素数密度为$log^{2}N$的结论,可以用米勒-拉宾的板子O(logn)判断大素数,暴力找出比n小的最大的一个大素数。

哥德巴赫猜想在小数据范围内成立,剩下部分如果是奇数就分成2 + 2 + 3 + 两个素数,如果是偶数就是2 + 2 + 2 + 两个素数。

(xk才是真正的数学选手,我连哥德巴赫猜想都不知道,就是打酱油的)

代码:$O(T × log^{3}N)$

  1. #include <iostream>
  2. #include <cmath>
  3. #include <map>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <set>
  8. #include <vector>
  9. #include <string>
  10. #include <queue>
  11. #include <stack>
  12. #include <iomanip>
  13. #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
  14. #define INF 0x3f3f3f3f
  15. #define sz(x) ((int)x.size())
  16. #define mp(a,b) make_pair(a, b)
  17. #define endl '\n'
  18.  
  19. using namespace std;
  20. typedef long long ll;
  21. typedef double db;
  22.  
  23. int random(int l, int r)
  24. {
  25. return rand() % (r - l) + l;
  26. }
  27.  
  28. ll fmul(ll a, ll b, ll mod)
  29. {
  30. a %= mod;
  31. ll res = ;
  32. for(;b;b>>=) {
  33. if(b & ) res = (res + a) % mod;
  34. a = (a + a) % mod;
  35. }
  36. return res;
  37. }
  38.  
  39. ll fpow(ll a, ll b, ll mod)
  40. {
  41. ll res = ;
  42. for(;b;b>>=) {
  43. if(b & ) res = fmul(res, a, mod);
  44. a = fmul(a, a, mod);
  45. }
  46. return res;
  47. }
  48.  
  49. bool witness(ll a, ll n, ll u, ll t)
  50. {
  51. ll x0 = fpow(a, u, n), x1;
  52. for(int i = ; i <= t; i++)
  53. {
  54. x1 = fmul(x0, x0, n);
  55. if(x1 == && x0 != && x0 != n - ) return false;
  56. x0 = x1;
  57. }
  58. if(x1 != ) return false;
  59. return true;
  60. }
  61.  
  62. bool isprime(ll n, int times = )
  63. {
  64. if(n == ) return true;
  65. if(n < || !(n & )) return false;
  66. ll u = n - , t = ;
  67. while(u % == ) {
  68. t++;
  69. u>>=;
  70. }
  71. while(times--)
  72. {
  73. ll a = random(, n - );
  74. if(!witness(a, n, u, t)) return false;
  75. }
  76. return true;
  77. }
  78.  
  79. int main()
  80. {
  81. srand(time());
  82. fast;
  83. int T;
  84. cin >> T;
  85. for(int kase = ; kase <= T; kase++)
  86. {
  87. cout << "Case " << kase << ": ";
  88. ll n;
  89. cin >> n;
  90. if(n < ) {
  91. cout << "IMPOSSIBLE\n";
  92. continue;
  93. }
  94. for(ll i = n - ; ; i--)
  95. {
  96. if(isprime(i)) {
  97. n -= i;
  98. cout << i;
  99. break;
  100. }
  101. }
  102. if(n & )
  103. {
  104. cout << " 2 2 3";
  105. n -= ;
  106. }
  107. else
  108. {
  109. cout << " 2 2 2";
  110. n -= ;
  111. }
  112. for(ll i = ; i <= n / ; i++)
  113. {
  114. if(isprime(i) && isprime(n - i))
  115. {
  116. cout << ' ' << i << ' ' << n - i << endl;
  117. break;
  118. }
  119. }
  120. }
  121. }

Problem G. Pastoral Life in Stardew Valley  01:13 (+) Solved by Dancepted (平方和公式)

设$f_{n, m}$表示n × m的草地上放稻草人的方案数,则:

$f_{n, m} = \sum_{i=1}^{n-2} \sum_{j=1}^{m-2}(n-i+1) × (m-j+1) = \frac{(n-1)(n-2) × (m-1)(m-2)}{4}$

设$F_{n, m}$表示n × m的土地上的答案,则:

$F_{n, m} = \sum_{i=3}^{n}\sum_{j=3}^{m} (n-i+1)×(m-j+1)×f_{i, j}  $

$= \sum_{i=3}^{n}\sum_{j=3}^{m} (n-i+1)×(m-j+1)×\frac{1}{4}i(i-1) × i(i-1)$

$= \frac{1}{4} \sum_{i=3}^{n}(n-i+1)(i-1)(i-2)\sum_{j=3}^{m}(m-j+1)(j-1)(j-2)$

令$g_{x} = \frac{1}{2} \sum_{i=3}^{x}(x-i+1)(i-1)(i-2)$,则$F_{n, m} = g_{n} * g_{m}$。

考虑预处理$g_{x}$:

①:$g_{3} = 1$

②:若已知$g_{x} = \frac{1}{2} \sum_{i=3}^{x}(x-i+1)(i-1)(i-2)$,则:

$g_{x+1} = \frac{1}{2} \sum_{i=3}^{x+1}(x-i+1+1)(i-1)(i-2)$

$= \frac{1}{2} \sum_{i=3}^{x+1}(x-i+1)(i-1)(i-2) + \frac{1}{2}\sum_{i=3}^{x+1}(i-1)(i-2) $

令$h_{x} =  \frac{1}{2}\sum_{i=3}^{x}(i-1)(i-2) $,则:

$g_{x+1} = g_{x} + h_{x}$,其中,用平方和公式等差数列求和公式可以O(1)地计算$h_{x}$。

代码:O(T + N)

  1. #include <iostream>
  2. #include <cmath>
  3. #include <map>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <set>
  8. #include <vector>
  9. #include <string>
  10. #include <queue>
  11. #include <stack>
  12. #include <iomanip>
  13. #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
  14. #define N 100005
  15. #define M 100005
  16. #define INF 0x3f3f3f3f
  17. #define mk(x) (1<<x) // be conscious if mask x exceeds int
  18. #define sz(x) ((int)x.size())
  19. #define upperdiv(a,b) (a/b + (a%b>0))
  20. #define mp(a,b) make_pair(a, b)
  21. #define endl '\n'
  22. #define lowbit(x) (x&-x)
  23.  
  24. using namespace std;
  25. typedef long long ll;
  26. typedef double db;
  27.  
  28. /** fast read **/
  29. template <typename T>
  30. inline void read(T &x) {
  31. x = ; T fg = ; char ch = getchar();
  32. while (!isdigit(ch)) {
  33. if (ch == '-') fg = -;
  34. ch = getchar();
  35. }
  36. while (isdigit(ch)) x = x*+ch-'', ch = getchar();
  37. x = fg * x;
  38. }
  39. template <typename T, typename... Args>
  40. inline void read(T &x, Args &... args) { read(x), read(args...); }
  41. template <typename T>
  42. inline void write(T x) {
  43. int len = ; char c[]; if (x < ) putchar('-'), x = -x;
  44. do{++len; c[len] = x% + '';} while (x /= );
  45. for (int i = len; i >= ; i--) putchar(c[i]);
  46. }
  47. template <typename T, typename... Args>
  48. inline void write(T x, Args ... args) { write(x), write(args...); }
  49.  
  50. #define md 1000000007
  51. ll mul(ll a, ll b) {
  52. return a * b % md;
  53. }
  54. ll add(ll a, ll b) {
  55. ll res = (a+b) % md;
  56. if (res < ) res += md;
  57. return res;
  58. }
  59. ll fpow(ll a, ll p) {
  60. ll res = ;
  61. for (; p; p >>= ) {
  62. if (p & )
  63. res = mul(res, a);
  64. a = mul(a, a);
  65. }
  66. return res;
  67. }
  68.  
  69. ll inv6, inv2;
  70. ll g[N];
  71. ll h(ll x) {
  72. ll res = ;
  73. res = add(res, mul(mul(x, mul(x+, *x+)), inv6));
  74. res = add(res, mul(mul(x, x+), inv2));
  75. res = mul(res, inv2);
  76. return res;
  77. }
  78. void init() {
  79. g[] = ;
  80. for (int i = ; i < N; i++) {
  81. g[i] = add(g[i-], h(i-));
  82. }
  83. }
  84. int main() {
  85. fast;
  86. int T; cin >> T;
  87. inv2 = fpow(, md-);
  88. inv6 = fpow(, md-);
  89. init();
  90. for (int kase = ; kase <= T; kase++) {
  91. int n, m; cin >> n >> m;
  92. ll ans = mul(g[n], g[m]);
  93. cout << "Case " << kase << ": " << ans << endl;
  94. }
  95. return ;
  96. }

Problem K. Mr. Panda and Kakin  02:36 (-2) Solved by Dancepted & xk (欧拉定理 逆元 素数密度)

根据欧拉定理的推论,$i^{a}$ mod n的循环节长度为$\phi(n)$,并且把n分解为$\sum_{p\in prime}p_{i}^{m_{i}}$后若$m_{i}$ <= 1,则$i^{a}$ mod n为纯循环(参考纯循环小数意会一下)。

那么只要能把$FLAG^{2^{30}+3}$凑成$FLAG^{1 mod \phi(n)}$就行了。

实际上$(x^{a})^{b} = x^{a×b}$,所以如果我们能求出$2^{30}+3$关于$phi(n)$的逆元,那么就有$(Flag^{2^{30}+3})^{逆元} = Flag^{1 mod \phi(n)} = Flag$。

而这个逆元是肯定存在的,因为$2^{30}+3$是一个质数,而且考虑到n的生成方式,n = p × q,phi(n) = (p-1)×(q-1)。而 p-1,q-1 < $2^{30}+3$,因此($2^{30}+3, \phi(n)$)= 1。

求$\phi(n)$的时候考虑素数密度,可以$O(log^{2}n)$暴力地找出n的两个素因子。

然后快速幂会爆long long,要用快速乘,然后这题的log又比较大,$log^{2}$会tle,所以要用O(1)的快速乘

PS:第一次写脑抽了以为$(x^{a})^{c} = x^{a+b}$,幸好没过样例。

PPS:这里吹爆jls在ccpc-camp讲的数论div2,听完之后碰到欧拉定理完全不虚,然后在comet oj的直播回放里就可以看(jls的盛世美颜)了。

代码:O(T×logn)

  1. #include <iostream>
  2. #include <cmath>
  3. #include <map>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <set>
  8. #include <vector>
  9. #include <string>
  10. #include <queue>
  11. #include <stack>
  12. #include <iomanip>
  13. #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
  14. #define N 100005
  15. #define M 100005
  16. #define INF 0x3f3f3f3f
  17. #define mk(x) (1<<x) // be conscious if mask x exceeds int
  18. #define sz(x) ((int)x.size())
  19. #define upperdiv(a,b) (a/b + (a%b>0))
  20. #define mp(a,b) make_pair(a, b)
  21. #define endl '\n'
  22. #define lowbit(x) (x&-x)
  23.  
  24. using namespace std;
  25. typedef long long ll;
  26. typedef double db;
  27. typedef long double ldb;
  28.  
  29. /** fast read **/
  30. template <typename T>
  31. inline void read(T &x) {
  32. x = ; T fg = ; char ch = getchar();
  33. while (!isdigit(ch)) {
  34. if (ch == '-') fg = -;
  35. ch = getchar();
  36. }
  37. while (isdigit(ch)) x = x*+ch-'', ch = getchar();
  38. x = fg * x;
  39. }
  40. template <typename T, typename... Args>
  41. inline void read(T &x, Args &... args) { read(x), read(args...); }
  42. template <typename T>
  43. inline void write(T x) {
  44. int len = ; char c[]; if (x < ) putchar('-'), x = -x;
  45. do{++len; c[len] = x% + '';} while (x /= );
  46. for (int i = len; i >= ; i--) putchar(c[i]);
  47. }
  48. template <typename T, typename... Args>
  49. inline void write(T x, Args ... args) { write(x), write(args...); }
  50.  
  51. ll gcd(ll a, ll b) {
  52. return b == ? a : gcd(b, a%b);
  53. }
  54. ll fmul(ll a, ll b, ll md) {
  55. a %= md, b %= md;
  56. ll c = (ldb) a * b / md;
  57. ll ans = a * b - c * md;
  58. if (ans < ) ans += md;
  59. else if (ans >= md) ans -= md;
  60. return ans;
  61. }
  62. ll fpow(ll a, ll p, ll md) {
  63. ll res = ;
  64. for (; p; p >>= ) {
  65. if (p & )
  66. res = fmul(res, a, md);
  67. a = fmul(a, a, md);
  68. }
  69. return res;
  70. }
  71.  
  72. ll exgcd(ll a, ll b, ll &x, ll &y) {
  73. if (a == && b == ) return -;
  74. if (b == ) {x = , y = ; return a;}
  75. ll d = exgcd(b, a%b, y, x);
  76. y -= a/b*x;
  77. return d;
  78. }
  79. ll mod_reverse(ll a, ll n) {
  80. ll x, y;
  81. ll d = exgcd(a, n, x, y);
  82. if (d == ) return (x % n + n) % n;
  83. return -;
  84. }
  85.  
  86. int main() {
  87. // fast;
  88. int T; cin >> T;
  89. for (int kase = ; kase <= T; kase++) {
  90. ll n, c; read(n, c);
  91. ll g = gcd(n, c);
  92. ll flag = , phin = ;
  93. if (g == ) {
  94. ll x = sqrt(n+0.5);
  95. if (x % == )
  96. x--;
  97. for (ll i = x; i >= ; i -= ) {
  98. if (n % i == ) {
  99. phin = (i-) * (n/i -);
  100. break;
  101. }
  102. }
  103. }
  104. else {
  105. phin = (g-) * (n/g - );
  106. }
  107. ll p = mod_reverse((<<)+, phin);
  108. flag = fpow(c, p, n);
  109.  
  110. printf("Case %d: %I64d\n", kase, flag);
  111. }
  112. return ;
  113. }
  114. /*
  115. 3
  116. 181857896263 167005790444
  117. 218128229323 156323229335
  118. 352308724847 218566715941
  119. */

Problem I. Cockroaches  04:19 (-1) Solved by Dancepted & lh & xk 

大概是个思维题吧。。。封榜20分钟才调出来qwq。(不过好像是第一次封榜后过题?)

能消灭的最多的小强数量只有两种情况。设小强数最多的行和列对应的小强数是r和c,那么能消灭最多的数量要么是r+c,要么是r+c-1。

然后遍历小强数最多的行(列)上的小强,统计能消灭r+c和r+c-1的方案数就行了。

具体的就是遍历小强数最多的行(列)上的小强的时候,看这些小强是否恰巧在小强数最多的列(行),如果在的话,说明激光中心在这个小强所在点上时,能消灭的数量是r+c-1而不是r+c。

若r+c的数量为0,那么用同样的方法再统计一下小强数次多的行(列)与小强数最多的列(行)对r+c-1的贡献就行了。

小强的坐标上限是1e9,要离散化一下。

特别地:依次最多消灭小强数为2的时候要特判一下,防止在两个不同点消灭了两个相同小强。

代码:O(T×nlogn)

  1. #include <iostream>
  2. #include <cmath>
  3. #include <map>
  4. #include <algorithm>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <set>
  8. #include <vector>
  9. #include <string>
  10. #include <queue>
  11. #include <stack>
  12. #include <iomanip>
  13. #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
  14. #define N 200005
  15. #define M 100005
  16. #define INF 0x3f3f3f3f
  17. #define mk(x) (1<<x) // be conscious if mask x exceeds int
  18. #define sz(x) ((int)x.size())
  19. #define upperdiv(a,b) (a/b + (a%b>0))
  20. #define mp(a,b) make_pair(a, b)
  21. #define endl '\n'
  22. #define lowbit(x) (x&-x)
  23.  
  24. using namespace std;
  25. typedef long long ll;
  26. typedef double db;
  27.  
  28. /** fast read **/
  29. template <typename T>
  30. inline void read(T &x) {
  31. x = ; T fg = ; char ch = getchar();
  32. while (!isdigit(ch)) {
  33. if (ch == '-') fg = -;
  34. ch = getchar();
  35. }
  36. while (isdigit(ch)) x = x*+ch-'', ch = getchar();
  37. x = fg * x;
  38. }
  39. template <typename T, typename... Args>
  40. inline void read(T &x, Args &... args) { read(x), read(args...); }
  41. template <typename T>
  42. inline void write(T x) {
  43. int len = ; char c[]; if (x < ) putchar('-'), x = -x;
  44. do{++len; c[len] = x% + '';} while (x /= );
  45. for (int i = len; i >= ; i--) putchar(c[i]);
  46. }
  47. template <typename T, typename... Args>
  48. inline void write(T x, Args ... args) { write(x), write(args...); }
  49.  
  50. int n;
  51. vector<int> vals;
  52. map<int, int> id;
  53. // int id[N<<1];
  54. struct Node{
  55. int r, c;
  56. }ns[N];
  57. vector <Node> vc[N], vr[N];
  58. int cntr1 = -, cntr2 = -, lenr1 = -, lenr2 = -;
  59. int cntc1 = -, cntc2 = -, lenc1 = -, lenc2 = -;
  60. void init() {
  61. sort(vals.begin(), vals.end());
  62. vals.erase(unique(vals.begin(), vals.end()), vals.end());
  63. for (int i = ; i < sz(vals); i++) {
  64. id[vals[i]] = i;
  65. vc[i].clear();
  66. vr[i].clear();
  67. }
  68.  
  69. for (int i = ; i <= n; i++) {
  70. int idr = id[ns[i].r], idc = id[ns[i].c];
  71. vr[idr].push_back(ns[i]);
  72. vc[idc].push_back(ns[i]);
  73. }
  74. cntr1 = -, cntr2 = -, lenr1 = -, lenr2 = -;
  75. cntc1 = -, cntc2 = -, lenc1 = -, lenc2 = -;
  76. for (int i = ; i < sz(vals); i++) {
  77. if (sz(vr[i]) > lenr1) {
  78. lenr2 = lenr1;
  79. cntr2 = cntr1;
  80. lenr1 = sz(vr[i]);
  81. cntr1 = ;
  82. }
  83. else if (sz(vr[i]) == lenr1) {
  84. cntr1++;
  85. }
  86. else if (sz(vr[i]) > lenr2) {
  87. lenr2 = sz(vr[i]);
  88. cntr2 = ;
  89. }
  90. else if (sz(vr[i]) == lenr2) {
  91. cntr2++;
  92. }
  93.  
  94. if (sz(vc[i]) > lenc1) {
  95. lenc2 = lenc1;
  96. cntc2 = cntc1;
  97. lenc1 = sz(vc[i]);
  98. cntc1 = ;
  99. }
  100. else if (sz(vc[i]) == lenc1) {
  101. cntc1++;
  102. }
  103. else if (sz(vc[i]) > lenc2) {
  104. lenc2 = sz(vc[i]);
  105. cntc2 = ;
  106. }
  107. else if (sz(vc[i]) == lenc2) {
  108. cntc2++;
  109. }
  110. }
  111. }
  112.  
  113. int main() {
  114. fast;
  115. int T; cin >> T;
  116. for (int kase = ; kase <= T; kase++) {
  117. cin >> n;
  118. id.clear();
  119. vals.clear();
  120. for (int i = ; i <= n; i++) {
  121. read(ns[i].r, ns[i].c);
  122. vals.push_back(ns[i].r);
  123. vals.push_back(ns[i].c);
  124. }
  125. init();
  126.  
  127. ll ans1 = lenc1 + lenr1, cnt1 = ;
  128. ll ans2 = lenc1 + lenr1 - , cnt2 = ;
  129. for (int i = ; i < sz(vals); i++) {
  130. if (sz(vc[i]) == lenc1) {
  131. cnt1 += cntr1;
  132. if (lenr2 == lenr1 - ) {
  133. cnt2 += cntr2;
  134. }
  135. for (Node &tmp : vc[i]) {
  136. if (sz(vr[id[tmp.r]]) == lenr1) {
  137. // share same point
  138. cnt1--;
  139. cnt2++;
  140. }
  141. else if (lenr2 == lenr1 - && sz(vr[id[tmp.r]]) == lenr2) {
  142. cnt2--;
  143. }
  144. }
  145. }
  146. else if (lenc2 == lenc1 - && sz(vc[i]) == lenc2) {
  147. cnt2 += cntr1;
  148. for (Node &tmp: vc[i]) {
  149. if (sz(vr[id[tmp.r]]) == lenr1) {
  150. // share same point
  151. cnt2--;
  152. }
  153. }
  154. }
  155. }
  156.  
  157. ll ans = , cnt = ;
  158. if (cnt1 > ) {
  159. ans = ans1, cnt = cnt1;
  160. }
  161. else {
  162. ans = ans2, cnt = cnt2;
  163. }
  164. if (ans == ) {
  165. cnt = 1LL * n * (n-) / ;
  166. }
  167. printf("Case %d: %I64d %I64d\n", kase, ans, cnt);
  168. }
  169. return ;
  170. }

Problem B. Balance of the Force 04:35(+) Solved by lh(贪心)

不能放在同一边的两个人连一条边,如果得到的图中有奇数环,则不可能。

然后枚举最小的能力值。贪心地寻找最小的最大值。

枚举下一个最小的能力值时,仅有当前最小能力值所在的环,和下一个最小能力值所在的环对应的能力值要更新,所以整个贪心可以是O(N)的。

代码:O(T×N)

  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <cstring>
  6. #define N 200005
  7. #define INF 0x3f3f3f3f
  8. #define fi first
  9. #define se second
  10.  
  11. using namespace std;
  12. typedef pair<int,int> pii;
  13.  
  14. /** fast read **/
  15. template <typename T>
  16. inline void read(T &x) {
  17. x = ; T fg = ; char ch = getchar();
  18. while (!isdigit(ch)) {
  19. if (ch == '-') fg = -;
  20. ch = getchar();
  21. }
  22. while (isdigit(ch)) x = x*+ch-'', ch = getchar();
  23. x = fg * x;
  24. }
  25. template <typename T, typename... Args>
  26. inline void read(T &x, Args &... args) { read(x), read(args...); }
  27. template <typename T>
  28. inline void write(T x) {
  29. int len = ; char c[]; if (x < ) putchar('-'), x = -x;
  30. do{++len; c[len] = x% + '';} while (x /= );
  31. for (int i = len; i >= ; i--) putchar(c[i]);
  32. }
  33. template <typename T, typename... Args>
  34. inline void write(T x, Args ... args) { write(x), write(args...); }
  35. int T;
  36. int n, m, ednum, top, col[N];
  37. int w[N][];
  38. struct node
  39. {
  40. int be, w;
  41. bool operator<(const node &other)const
  42. {
  43. return w < other.w;
  44. }
  45. } s[N << ];
  46. struct Unite
  47. {
  48. int cur, maxn[], minx[];
  49. } st[N];
  50. int hed[N << ], nxt[N << ], to[N << ];
  51. void add(int u, int v)
  52. {
  53. to[++ednum] = v;
  54. nxt[ednum] = hed[u], hed[u] = ednum;
  55. }
  56. bool dfs(int v)
  57. {
  58. st[top].maxn[] = max(st[top].maxn[], w[v][col[v]]), st[top].minx[] = min(st[top].minx[], w[v][col[v]]);
  59. st[top].maxn[] = max(st[top].maxn[], w[v][col[v] ^ ]), st[top].minx[] = min(st[top].minx[], w[v][col[v] ^ ]);
  60. for (int i = hed[v]; i; i = nxt[i])
  61. {
  62. int u = to[i];
  63. if (col[u] == col[v])
  64. return false;
  65. if (col[u] != -)
  66. continue;
  67. col[u] = ^ col[v];
  68. if (dfs(u) == false)
  69. return false;
  70. }
  71. return true;
  72. }
  73. int save[N], ansmax;
  74. bool reduce()
  75. {
  76. while (top)
  77. {
  78. int id = save[top];
  79. if (st[id].cur == )
  80. return false;
  81. ansmax = max(ansmax, st[id].maxn[]), st[id].cur = , --top;
  82. }
  83. return true;
  84. }
  85. int main() {
  86. read(T);
  87. int u, v, cnt;
  88. int casecnt = ;
  89. while (T--)
  90. {
  91. ++casecnt;
  92. read(n, m), ednum = top = , memset(hed, , sizeof(int) * (n + )), memset(col, -, sizeof(int) * (n + ));
  93. for (int i = ;i <= m; ++i)
  94. read(u, v), add(u, v), add(v, u);
  95. for (int i = ;i <= n; ++i)
  96. read(w[i][], w[i][]);
  97. bool flag = true;
  98. ansmax = , top = , cnt = ;
  99. int ans = INF;
  100. for (int i = ;i <= n; ++i)
  101. {
  102. if (col[i] != -) continue;
  103. ++top, st[top].cur = , st[top].maxn[] = st[top].maxn[] = ;
  104. st[top].minx[] = st[top].minx[] = INF, col[i] = , flag &= dfs(i);
  105. if (flag == false)
  106. break;
  107. if (st[top].minx[] > st[top].minx[])
  108. swap(st[top].minx[], st[top].minx[]), swap(st[top].maxn[], st[top].maxn[]);
  109. if (st[top].maxn[] >= st[top].maxn[])
  110. st[top].cur = ;
  111. else
  112. s[++cnt] = node{top, st[top].minx[]};
  113. s[++cnt] = node{top, st[top].minx[]};
  114. ansmax = max(ansmax, st[top].maxn[st[top].cur]);
  115. }
  116. printf("Case %d: ", casecnt);
  117. if (flag == false)
  118. {
  119. puts("IMPOSSIBLE");
  120. continue;
  121. }
  122. sort(s + , s + + cnt);
  123. int i = ;
  124. top = ;
  125. while (flag && i <= cnt)
  126. {
  127. ans = min(ans, ansmax - s[i].w);
  128. save[++top] = s[i].be;
  129. if (s[i].w != s[i + ].w)
  130. {
  131. flag &= reduce();
  132. if (!flag)
  133. break;
  134. }
  135. ++i;
  136. }
  137. write(ans), putchar('\n');
  138. }
  139. return ;
  140. }

还有不到一周就是CCPC-Final了,这周每两天一套题,冲鸭。


总结:

浮躁的菜逼选手贡献全部罚时。

模拟赛小结:2018 China Collegiate Programming Contest Final (CCPC-Final 2018)的更多相关文章

  1. 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定理

    2018 China Collegiate Programming Contest Final (CCPC-Final 2018)-K - Mr. Panda and Kakin-中国剩余定理+同余定 ...

  2. 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)(A B G I L)

    A:签到题,正常模拟即可. #include<bits/stdc++.h> using namespace std; ; struct node{ int id, time; }; nod ...

  3. 2018 China Collegiate Programming Contest Final (CCPC-Final 2018)

    Problem A. Mischievous Problem Setter 签到. #include <bits/stdc++.h> using namespace std; #defin ...

  4. 2018 German Collegiate Programming Contest (GCPC 18)

    2018 German Collegiate Programming Contest (GCPC 18) Attack on Alpha-Zet 建树,求lca 代码: #include <al ...

  5. The 2015 China Collegiate Programming Contest A. Secrete Master Plan hdu5540

    Secrete Master Plan Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Othe ...

  6. The 2015 China Collegiate Programming Contest Game Rooms

    Game Rooms Time Limit: 4000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  7. 2016 China Collegiate Programming Contest Final

    2016 China Collegiate Programming Contest Final Table of Contents 2016 China Collegiate Programming ...

  8. (寒假GYM开黑)2018 German Collegiate Programming Contest (GCPC 18)

    layout: post title: 2018 German Collegiate Programming Contest (GCPC 18) author: "luowentaoaa&q ...

  9. 模拟赛小结:2017 China Collegiate Programming Contest Final (CCPC-Final 2017)

    比赛链接:传送门 前期大顺风,2:30金区中游.后期开题乏力,掉到银尾.4:59绝杀I,但罚时太高卡在银首. Problem A - Dogs and Cages 00:09:45 (+) Solve ...

随机推荐

  1. centos 7 删除 virbr0 虚拟网卡

    出现虚拟网卡是因为安装时启用了 libvirtd 服务后生成的关闭方法virsh net-list名称               状态     自动开始  持久------------------- ...

  2. Java实现批量下载选中文件功能

    1.在action中定义变量 ? 1 2 3 4 5 6 private List<String> downLoadPaths = new ArrayList<String>( ...

  3. java:常见问题(解决获取properties乱码,解决poi自适应宽度)

    1.解决获取properties乱码 File cf = new File("D:\\app\\java_jar\\config.properties"); String[] pa ...

  4. python多媒体文件抽取

    多文件抽取有:只获取url,或直接下载,下面是怎么将数据下载下来,并显示进度. 本节主要介绍urllib模块提供的urlretrieve()函数.urlretrieve()方法直接将远程数据下载到本地 ...

  5. Linux进程间通信(IPC)之信号量

    [Linux]进程间通信(IPC)之信号量详解与测试用例 2017年03月22日 17:28:50 阅读数:2255 学习环境centos6.5 Linux内核2.6 进程间通信概述 1. 进程通信机 ...

  6. ubuntu安装成功之后需要做些什么?

    1.安装VMtool 1.1打开虚拟机之后-> 安装VMtool 1.2 点击之后,桌面就会出现一个VMtool光驱文件,如果提示光驱被占用就先用root登录 1.3在命令行挂载 sudo mo ...

  7. Centos7永久关闭防火墙

    Centos7永久关闭防火墙 查看防火墙状态: systemctl status firewalld.service 绿的running表示防火墙开启 执行关闭命令: systemctl stop f ...

  8. Leetcode之广度优先搜索(BFS)专题-752. 打开转盘锁(Open the Lock)

    Leetcode之广度优先搜索(BFS)专题-752. 打开转盘锁(Open the Lock) BFS入门详解:Leetcode之广度优先搜索(BFS)专题-429. N叉树的层序遍历(N-ary ...

  9. 【Linux-驱动】在sysfs下创建对应的class节点---class_create

    在编写简单字符设备驱动的时候,可以使用宏class_create在sysfs下创建对应的class节点,便于用户管理设备: #define class_create(owner, name) \ ({ ...

  10. Longest Palindromic Subsequence

    Given a string s, find the longest palindromic subsequence's length in s. You may assume that the ma ...