[关闭]
@Dmaxiya 2018-08-17T02:28:48.000000Z 字数 5669 阅读 1772

Codeforces Round #458 (Div. 1 + Div. 2)

Codeforces


Contests 链接:Codeforces Round #458 (Div. 1 + Div. 2)
过题数:2
排名:1691/8398

A. Perfect Squares

题意

给定一个长度为 的序列 ,找到这个序列中最大的开方不是整数的数字。

数据范围

题解

按照题意跑一遍。

过题代码

  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. int n;
  21. LL tmp;
  22. bool judge(LL x) {
  23. if(x < 0) {
  24. return true;
  25. }
  26. LL xx = sqrt(x);
  27. if(xx * xx == x) {
  28. return false;
  29. }
  30. return true;
  31. }
  32. int main() {
  33. #ifdef LOCAL
  34. freopen("test.txt", "r", stdin);
  35. // freopen("out.txt", "w", stdout);
  36. #endif // LOCAL
  37. ios::sync_with_stdio(false);
  38. while(scanf("%d", &n) != EOF) {
  39. LL ans = INT_MIN;
  40. for(int i = 0; i < n; ++i) {
  41. scanf("%I64d", &tmp);
  42. if(judge(tmp)) {
  43. ans = max(ans, tmp);
  44. }
  45. }
  46. printf("%I64d\n", ans);
  47. }
  48. return 0;
  49. }

B. Conan and Agasa play a Card Game

题意

柯南和阿笠博士玩一场博弈游戏,给定 张卡片,每张卡片上的数字为 ,对于每次操作,一方可以选择一张卡片,然后将其他所有小于该数字的卡片拿掉,最后无法进行操作的一方失败。柯南先手,如果两人都采取最优策略,问谁会获胜。

数据范围

题解

如果最大的数字有 个,如果 为偶数,则先拿最大的数字的人必败,否则必胜,所以如果最大的数字有偶数个,则双方肯定尽量不先拿最大的数字,对于次大的数字也是如此,一直往小了找,如果某个数字出现的次数为奇数,则先拿到这个数字的一方必胜,所以先手一定会直接取这个个数为奇数的数字。所以只要存在个数为奇数的数字,先手必胜,否则必败。

过题代码

  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. int n, tmp;
  21. bool flag;
  22. map<int, int> mp;
  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", &n) != EOF) {
  30. mp.clear();
  31. for(int i = 0; i < n; ++i) {
  32. scanf("%d", &tmp);
  33. ++mp[tmp];
  34. }
  35. flag = false;
  36. map<int, int>::iterator it;
  37. for(it = mp.begin(); it != mp.end(); ++it) {
  38. if(it->second % 2 == 1) {
  39. flag = true;
  40. break;
  41. }
  42. }
  43. if(flag) {
  44. printf("Conan\n");
  45. } else {
  46. printf("Agasa\n");
  47. }
  48. }
  49. return 0;
  50. }

C. Travelling Salesman and Special Numbers

题意

定义一个操作,对于数字 ,进行一次操作后, 变为 对应的二进制数中,数字 的个数,例如, 进行一次操作后变为 ,再进行一次操作后变为 。现在,对于数字 ,询问从 到 中,最少进行 次操作后变为 的数字有多少个,输出对 后的答案, 以二进制形式给出。

数据范围

题解

对于 以内的数字,进行一次操作后,必然变成 以内的数字,所以可以先预处理出 以内的数字,至少进行多少次操作后变为 ,然后对 到 的数字,询问哪些数字最少可以经过 次操作变为 ,若数字 可以经过 次操作变为 ,则用数位 算出从 到 之间有多少个二进制中含有 个 的数字,加到答案上。注意特判 和 的情况。

过题代码

  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. const int MOD = 1000000000 + 7;
  22. char n[maxn];
  23. int k, len, ans;
  24. int step[maxn];
  25. int dp[maxn][maxn][2];
  26. int dfs(int pos, int r, int limit) {
  27. if(r < 0) {
  28. return 0;
  29. }
  30. if(pos == len) {
  31. if(r == 0) {
  32. return 1;
  33. } else {
  34. return 0;
  35. }
  36. }
  37. if(!limit && dp[pos][r][limit] != -1) {
  38. return dp[pos][r][limit];
  39. }
  40. int up = limit? (n[pos] - '0'): 1;
  41. int ans = 0;
  42. for(int i = 0; i <= up; ++i) {
  43. if(i == 1) {
  44. ans += dfs(pos + 1, r - 1, limit && i == n[pos] - '0');
  45. ans %= MOD;
  46. } else {
  47. ans += dfs(pos + 1, r, limit && i == n[pos] - '0');
  48. ans %= MOD;
  49. }
  50. }
  51. if(!limit) {
  52. dp[pos][r][limit] = ans;
  53. }
  54. return ans;
  55. }
  56. int get_one(int x) {
  57. int ret = 0;
  58. while(x != 0) {
  59. if(x % 2 == 1) {
  60. ++ret;
  61. }
  62. x /= 2;
  63. }
  64. return ret;
  65. }
  66. int main() {
  67. #ifdef LOCAL
  68. freopen("test.txt", "r", stdin);
  69. // freopen("out.txt", "w", stdout);
  70. #endif // LOCAL
  71. // ios::sync_with_stdio(false);
  72. step[1] = 0;
  73. for(int i = 2; i < maxn; ++i) {
  74. step[i] = step[get_one(i)] + 1;
  75. }
  76. while(scanf("%s%d", n, &k) != EOF) {
  77. if(k == 0) {
  78. printf("1\n");
  79. continue;
  80. }
  81. ans = 0;
  82. len = strlen(n);
  83. memset(dp, -1, sizeof(dp));
  84. for(int i = 1; i < maxn; ++i) {
  85. if(step[i] == k - 1) {
  86. ans += dfs(0, i, 1);
  87. ans %= MOD;
  88. // printf("dfs(%d) = %d\n", i, dfs(0, i, 1));
  89. }
  90. }
  91. if(k == 1) {
  92. --ans;
  93. ans = (ans + MOD) % MOD;
  94. }
  95. printf("%d\n", ans);
  96. }
  97. return 0;
  98. }

D. Bash and a Tough Math Puzzle

题意

给定 个数字的序列 ,进行 次操作,每次操作有两种形式:

  • 询问能否在区间 上最多修改一个数字,使得该区间上所有数字都是 的倍数;
  • 将第 个数字修改为 。

对于每次询问,输出 或者 。

数据范围

题解

用线段树存区间 ,对于每次询问,判断区间 上不是 的倍数的数字是否多于一个,若多于 个,则不是。判断的时候注意剪枝,若左子节点已经有多于两个数字不是 的倍数,则不必判断右子节点。

过题代码

  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 = 500000 + 100;
  21. int n, q, command, l, r, x, Index, y;
  22. int ans;
  23. int Gcd[maxn << 2];
  24. int gcd(int x, int y) {
  25. if(y == 0) {
  26. return x;
  27. }
  28. return gcd(y, x % y);
  29. }
  30. void push_up(int rt) {
  31. Gcd[rt] = gcd(Gcd[rt << 1], Gcd[rt << 1 | 1]);
  32. }
  33. void build(int l, int r, int rt) {
  34. if(l == r) {
  35. scanf("%d", &Gcd[rt]);
  36. return ;
  37. }
  38. int m = (l + r) >> 1;
  39. build(l, m, rt << 1);
  40. build(m + 1, r, rt << 1 | 1);
  41. push_up(rt);
  42. }
  43. void update(int Index, int tmp, int l, int r, int rt) {
  44. if(l == r) {
  45. Gcd[rt] = tmp;
  46. return ;
  47. }
  48. int m = (l + r) >> 1;
  49. if(Index <= m) {
  50. update(Index, tmp, l, m, rt << 1);
  51. } else {
  52. update(Index, tmp, m + 1, r, rt << 1 | 1);
  53. }
  54. push_up(rt);
  55. }
  56. int query(int L, int R, int tmp, int l, int r, int rt) {
  57. if(L <= l && r <= R) {
  58. if(Gcd[rt] % tmp == 0) {
  59. return 0;
  60. }
  61. }
  62. if(l == r) {
  63. return (Gcd[rt] % tmp != 0);
  64. }
  65. int m = (l + r) >> 1;
  66. int ret = 0;
  67. if(L <= m) {
  68. ret += query(L, R, tmp, l, m, rt << 1);
  69. }
  70. if(ret >= 2) {
  71. return 2;
  72. }
  73. if(R > m) {
  74. ret += query(L, R, tmp, m + 1, r, rt << 1 | 1);
  75. }
  76. if(ret >= 2) {
  77. ret = 2;
  78. }
  79. return ret;
  80. }
  81. void Print() {
  82. for(int i = 1; i <= 10; ++i) {
  83. printf("Gcd[%d] = %d\n", i, Gcd[i]);
  84. }
  85. }
  86. int main() {
  87. #ifdef LOCAL
  88. freopen("test.txt", "r", stdin);
  89. // freopen("out.txt", "w", stdout);
  90. #endif // LOCAL
  91. // ios::sync_with_stdio(false);
  92. while(scanf("%d", &n) != EOF) {
  93. build(1, n, 1);
  94. scanf("%d", &q);
  95. for(int i = 0; i < q; ++i) {
  96. scanf("%d", &command);
  97. if(command == 1) {
  98. scanf("%d%d%d", &l, &r, &x);
  99. // printf("l = %d r = %d x = %d\n", l, r, x);
  100. ans = query(l, r, x, 1, n, 1);
  101. // printf("ans = %d\n", ans);
  102. if(ans <= 1) {
  103. printf("YES\n");
  104. } else {
  105. printf("NO\n");
  106. }
  107. } else {
  108. scanf("%d%d", &Index, &y);
  109. update(Index, y, 1, n, 1);
  110. // Print();
  111. }
  112. }
  113. }
  114. return 0;
  115. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注