[关闭]
@Dmaxiya 2018-08-17T10:27:12.000000Z 字数 7061 阅读 873

Codeforces Round #383 (Div. 2)

Codeforces


Contests 链接:Codeforces Round #383 (Div. 2)
过题数:4
排名:181/14510

A. Arpa's hard exam and Mehrdad's naive cheat

题意

的最后一位数。

数据范围

题解

快速幂。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long long
  20. const int MOD = 10;
  21. LL n;
  22. LL fast_pow(LL res, LL n) {
  23. LL ans = 1;
  24. for(ans = 1; n != 0; n >>= 1) {
  25. if(n % 2 == 1) {
  26. ans *= res;
  27. ans %= MOD;
  28. }
  29. res *= res;
  30. res %= MOD;
  31. }
  32. return ans;
  33. }
  34. int main() {
  35. #ifdef LOCAL
  36. freopen("test.txt", "r", stdin);
  37. // freopen("out.txt", "w", stdout);
  38. #endif // LOCAL
  39. ios::sync_with_stdio(false);
  40. while(scanf("%I64d", &n) != EOF) {
  41. printf("%I64d\n", fast_pow(1378, n) % 10);
  42. }
  43. return 0;
  44. }

B. Arpa's obvious problem and Mehrdad's terrible solution

题意

给定一个长度为 的序列 ,求这个序列中满足 的所有 有序对个数。其中 是按位异或运算符。

数据范围

题解

利用 的逆运算是其本身,先对原序列排序,对于每个 二分找到所有 的个数,由于这样找到的结果是 的无序对,所以最后的结果要除以 ,要注意 的情况,此时 ,所以当 时,对每个 统计出所有等于 的无序对个数时,应减去它本身。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long long
  20. const int maxn = 100000 + 100;
  21. int n, x;
  22. int num[maxn];
  23. int main() {
  24. #ifdef LOCAL
  25. freopen("test.txt", "r", stdin);
  26. // freopen("out.txt", "w", stdout);
  27. #endif // LOCAL
  28. ios::sync_with_stdio(false);
  29. while(scanf("%d%d", &n, &x) != EOF) {
  30. for(int i = 0; i < n; ++i) {
  31. scanf("%d", &num[i]);
  32. }
  33. sort(num, num + n);
  34. int *it1, *it2;
  35. LL ans = 0;
  36. for(int i = 0; i < n; ++i) {
  37. it1 = lower_bound(num, num + n, num[i] ^ x);
  38. it2 = upper_bound(num, num + n, num[i] ^ x);
  39. ans += it2 - it1;
  40. if(x == 0) {
  41. --ans;
  42. }
  43. }
  44. printf("%I64d\n", ans / 2);
  45. }
  46. return 0;
  47. }

C. Arpa's loud Owf and Mehrdad's evil plan

题意

给出一个长度为 的序列 ,表示第 个人将 个人,每一轮每个人往后 一个人(相当于把信息往后一个人传),现在要求经过的最少的轮数,使得满足这样一个条件:经过 轮后,如果第 个人的信息正好传达到第 个人,那么第 个人的信息也正好传达到第 个人,如果不存在这样的轮数,输出

数据范围

题解

连一条有向边,那么这个有向图上所有边一定都在环上,如果存在不在环上的点,那么这个点所在的链的起点一定无法收到消息,所以这样的序列就是不满足条件的序列,所以不满足条件的图,就是存在入度为 的节点,(因为每个点的出度一定都等于 ,所以如果存在链,一定是由入度为 的点到达的)这种情况下输出
其他情况下,序列构成的有向图一定是一个个简单环,在环上的信息传递,如果环上节点的个数为奇数个(设为 ),要使 之间能互相传达信息,至少要经过 轮,如果环上节点数为偶数个,则满足条件的最少的轮数应该是 ,对所有的环的最少轮数取最小公倍数,就是答案。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long long
  20. const int maxn = 100 + 100;
  21. int n, x;
  22. LL ans;
  23. bool vis[maxn];
  24. int num[maxn], fa[maxn], deg[maxn];
  25. void Init() {
  26. for(int i = 1; i <= n; ++i) {
  27. vis[i] = false;
  28. fa[i] = i;
  29. num[i] = 1;
  30. deg[i] = 0;
  31. }
  32. }
  33. int Find(int x) {
  34. return (x == fa[x]? x: fa[x] = Find(fa[x]));
  35. }
  36. void unit(int x, int y) {
  37. int xx = Find(x);
  38. int yy = Find(y);
  39. if(xx != yy) {
  40. fa[xx] = yy;
  41. num[yy] += num[xx];
  42. }
  43. }
  44. LL gcd(LL x, LL y) {
  45. return (y == 0? x: gcd(y, x % y));
  46. }
  47. LL lcm(LL x, LL y) {
  48. return x / gcd(x, y) * y;
  49. }
  50. int main() {
  51. #ifdef LOCAL
  52. freopen("test.txt", "r", stdin);
  53. // freopen("test1.out", "w", stdout);
  54. #endif // LOCAL
  55. ios::sync_with_stdio(false);
  56. while(scanf("%d", &n) != EOF) {
  57. ans = 1;
  58. Init();
  59. for(int i = 1; i <= n; ++i) {
  60. scanf("%d", &x);
  61. unit(x, i);
  62. ++deg[x];
  63. }
  64. bool flag = true;
  65. for(int i = 1; i <= n; ++i) {
  66. if(deg[i] == 0) {
  67. flag = false;
  68. break;
  69. }
  70. }
  71. if(!flag) {
  72. printf("-1\n");
  73. continue;
  74. }
  75. for(int i = 1; i <= n; ++i) {
  76. int f = Find(i);
  77. if(!vis[f]) {
  78. vis[f] = true;
  79. if(num[f] % 2 == 0) {
  80. ans = lcm(ans, num[f] / 2);
  81. } else {
  82. ans = lcm(ans, num[f]);
  83. }
  84. }
  85. }
  86. printf("%I64d\n", ans);
  87. }
  88. return 0;
  89. }

D. Arpa's weak amphitheater and Mehrdad's valuable Hoses

题意

想要邀请一些女生来到他的舞会,每个女生都有对应的美丽值 和重量 ,这个剧场只能容纳下总重量为 的人。其中有 对女生 互为朋友,且某个女生的朋友的朋友也是这个女生的朋友,为了不让她们伤心,同一群朋友中,要么最多邀请其中的一个,要么全都邀请,问在总重量不超过 的情况下,能够邀请到的最大的总的美丽值

数据范围

题解

用个并查集把互为朋友的女生放到同一个 里,然后跑个分组背包。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long long
  20. const int maxn = 1000 + 100;
  21. int n, m, W, u, v, Index, ii;
  22. int fa[maxn];
  23. int w[maxn], b[maxn];
  24. int w_tot[maxn], b_tot[maxn];
  25. int dp[2][maxn];
  26. vector<int> G[maxn];
  27. void Init() {
  28. ii = 1;
  29. for(int i = 1; i <= n; ++i) {
  30. fa[i] = i;
  31. G[i].clear();
  32. }
  33. for(int i = 0; i <= W; ++i) {
  34. dp[0][i] = dp[1][i] = 0;
  35. }
  36. }
  37. int Find(int x) {
  38. return (x == fa[x]? x: fa[x] = Find(fa[x]));
  39. }
  40. void unit(int x, int y) {
  41. int xx = Find(x);
  42. int yy = Find(y);
  43. if(xx != yy) {
  44. fa[xx] = yy;
  45. b_tot[yy] += b_tot[xx];
  46. w_tot[yy] += w_tot[xx];
  47. }
  48. }
  49. int main() {
  50. #ifdef LOCAL
  51. freopen("test.txt", "r", stdin);
  52. // freopen("test1.out", "w", stdout);
  53. #endif // LOCAL
  54. ios::sync_with_stdio(false);
  55. while(scanf("%d%d%d", &n, &m, &W) != EOF) {
  56. Init();
  57. for(int i = 1; i <= n; ++i) {
  58. scanf("%d", &w[i]);
  59. w_tot[i] = w[i];
  60. }
  61. for(int i = 1; i <= n; ++i) {
  62. scanf("%d", &b[i]);
  63. b_tot[i] = b[i];
  64. }
  65. for(int i = 0; i < m; ++i) {
  66. scanf("%d%d", &u, &v);
  67. unit(u, v);
  68. }
  69. for(int i = 1; i <= n; ++i) {
  70. G[Find(i)].push_back(i);
  71. }
  72. for(int i = 1; i <= n; ++i) {
  73. int len = G[i].size();
  74. if(len == 0) {
  75. continue;
  76. }
  77. Index = ii;
  78. ii = (Index + 1) % 2;
  79. memcpy(dp[Index], dp[ii], sizeof((dp[Index])));
  80. for(int j = 0; j < len; ++j) {
  81. for(int k = w[G[i][j]]; k <= W; ++k) {
  82. dp[Index][k] = max(dp[Index][k], dp[ii][k - w[G[i][j]]] + b[G[i][j]]);
  83. }
  84. }
  85. for(int k = w_tot[i]; k <= W; ++k) {
  86. dp[Index][k] = max(dp[Index][k], dp[ii][k - w_tot[i]] + b_tot[i]);
  87. }
  88. }
  89. printf("%d\n", dp[Index][W]);
  90. }
  91. return 0;
  92. }

E. Arpa's overnight party and Mehrdad's silent entering

题意

对情侣坐在一个圆桌上,这个圆桌有 个座位,第 对情侣的座位为 ,桌上总共有两种食物分别用 表示,现在要求一种满足以下条件的食物的分配方案:

  1. 每个人都有一种食物;
  2. 每个男生的食物都要和他伴侣的食物不相同;
  3. 餐桌上任意连续的三个人之间至少有两个人的食物不同,其中第 个座位和第 个座位是相邻的。

如果不存在满足条件的方案,则输出

数据范围

题解

如果不管第 个条件,这就是一个二分图染色,给出第三个条件后,可以通过构造,将这题转化为一个二分图,构造的方法就是,将座位 之间连边,这样把整张图展开就是一个一个的环,且每个环上节点的个数都是偶数,所以无论如何,染色方案一定是合法的,不可能出现 的情况。

过题代码

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <climits>
  6. #include <cstring>
  7. #include <string>
  8. #include <vector>
  9. #include <list>
  10. #include <queue>
  11. #include <stack>
  12. #include <map>
  13. #include <set>
  14. #include <bitset>
  15. #include <algorithm>
  16. #include <functional>
  17. #include <iomanip>
  18. using namespace std;
  19. #define LL long long
  20. const int maxn = 200000 + 100;
  21. int n;
  22. bool vis[maxn];
  23. int color[maxn], u[maxn], v[maxn];
  24. vector<int> G[maxn];
  25. queue<int> que;
  26. void Init() {
  27. for(int i = 1; i <= 2 * n; ++i) {
  28. G[i].clear();
  29. color[i] = 0;
  30. vis[i] = false;
  31. }
  32. for(int i = 1; i <= 2 * n; i += 2) {
  33. G[i].push_back(i + 1);
  34. G[i + 1].push_back(i);
  35. }
  36. }
  37. void bfs(int s) {
  38. color[s] = 1;
  39. que.push(s);
  40. while(!que.empty()) {
  41. int tmp = que.front();
  42. que.pop();
  43. vis[tmp] = true;
  44. int len = G[tmp].size();
  45. for(int i = 0; i < len; ++i) {
  46. int pos = G[tmp][i];
  47. if(color[pos] == 0) {
  48. color[pos] = 3 - color[tmp];
  49. que.push(pos);
  50. }
  51. }
  52. }
  53. }
  54. int main() {
  55. #ifdef LOCAL
  56. freopen("test.txt", "r", stdin);
  57. // freopen("test1.out", "w", stdout);
  58. #endif // LOCAL
  59. ios::sync_with_stdio(false);
  60. while(scanf("%d", &n) != EOF) {
  61. Init();
  62. for(int i = 0; i < n; ++i) {
  63. scanf("%d%d", &u[i], &v[i]);
  64. G[u[i]].push_back(v[i]);
  65. G[v[i]].push_back(u[i]);
  66. }
  67. for(int i = 1; i <= 2 * n; ++i) {
  68. if(!vis[i]) {
  69. bfs(i);
  70. }
  71. }
  72. for(int i = 0; i < n; ++i) {
  73. printf("%d %d\n", color[u[i]], color[v[i]]);
  74. }
  75. }
  76. return 0;
  77. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注