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

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. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注