A Odd Set

题目大意

给一个数n,给2*n个数,将他们分为n组,每组两个数,问能否使每组数的和为奇数

主要思路

只有奇数+偶数=奇数,那么只有当奇数个数==偶数个数时才能凑成

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. const int N = 200010;
  18. int n, a[N];
  19. signed main(void)
  20. {
  21. int T;
  22. cin >> T;
  23. while(T--)
  24. {
  25. int odd = 0, even = 0;
  26. cin >> n;
  27. for(int i = 0; i < 2 * n; i++)
  28. {
  29. int t;
  30. cin >> t;
  31. if(t % 2) odd++;
  32. else even++;
  33. }
  34. if(odd == even) puts("Yes");
  35. else puts("No");
  36. }
  37. return 0;
  38. }

B Plus and Multiply

题目大意

给定一个数a, 一个数b,同时还有一个从1开始的数列,数列无限长,数列中的数可以从数列中任选一个数乘a或者加b来添加,问给你一个数n,这个数是否在这个数列中

主要思路

假定一个数x = ((1 + b) a + b + b)) a + b = (1 + b) a a + (2a + 1)b = a _ a + (a^2 + 2_a + 1) * b,也就是说任意一个在数列中的数,一定通过可以减去几个a来让这个数成为b的倍数,所以可以通过将给定的数n通过减0个a, 1个a…判断每个数是否是b的倍数即可

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. signed main(void)
  18. {
  19. int T;
  20. cin >> T;
  21. while(T--)
  22. {
  23. int n, a, b;
  24. cin >> n >> a >> b;
  25. bool flag = false;
  26. for(int i = 1; i <= n; i *= a)
  27. {
  28. if((n - i) % b == 0)
  29. {
  30. flag = true;
  31. }
  32. if(a == 1) break;
  33. }
  34. if(flag) puts("Yes");
  35. else puts("No");
  36. }
  37. return 0;
  38. }

C Strange Function

题目大意

定义一个f(x)为x%i不等于0的最小正整数i,给定一个数n,求f(1) + f(2) + …+ f(n)的和

主要思路

首先我们考虑f(x)的取值最大为41,为42时说明x是141的最小公倍数为219060189739591200,大于n的取值范围。

其次我们考虑2~41每个值对答案的贡献,所有奇数答案都为2,偶数答案一定大于2,每个数的贡献至少为2,所以我们先把答案初始化为n*2。

2比较特殊考虑完毕,如果f(x)想要有3~41中某个数i的贡献,那么x一定为1 ~ i - 1的最小公倍数的倍数,统计比n小的中有多少数是1 ~ i - 1的最小公倍数的倍数就相当于n / lcm(1 ~ i - 1), 这个数的含义是有多少数的f(x)至少能取到i,如果至少能取到i那么对答案贡献+1,所以3~41中某个数i的贡献为n / lcm(1 ~ i - 1)

AC代码

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <algorithm>
  5. #include <stack>
  6. #include <string>
  7. #include <cmath>
  8. #include <unordered_map>
  9. #include <queue>
  10. #include <map>
  11. using namespace std;
  12. #define int long long
  13. #define debug(a) cout << #a << " = " << a << endl;
  14. #define x first
  15. #define y second
  16. typedef pair<int, int> P;
  17. int gcd(int a, int b)
  18. {
  19. return b ? gcd(b, a % b) : a;
  20. }
  21. const int N = 50, mod = 1000000007;
  22. int a[N];
  23. signed main(void)
  24. {
  25. int x = 2;
  26. for(int i = 1; i <= 42; i++)
  27. {
  28. a[i] = x;
  29. x = x * i / gcd(x, i);
  30. }
  31. cout << a[42] << endl;
  32. int T;
  33. cin >> T;
  34. while(T--)
  35. {
  36. int n;
  37. cin >> n;
  38. int ans = n * 2;
  39. for(int i = 3; i <= 41; i++) ans = (ans + n / a[i]) % mod;
  40. cout << ans << endl;
  41. }
  42. return 0;
  43. }