@Dmaxiya
2020-12-12T07:26:27.000000Z
字数 6253
阅读 1250
Codeforces
Contests 链接:Codeforces Round #439 (Div. 2)
过题数:3
排名:623/10987
和 两个人分别列出 个数字 和 ,其中对于任意 有 ,问对于这个数组中有多少个 对,使得 的值等于这两个序列当中的某一个数字,如果答案为偶数,则 获胜,否则 获胜。
第一行为一个整数 ,第二行为 个互不相等的整数 ,表示 给出的 个数字,第三行为 个互不相等的整数 表示 给出的 个数字,其中
输出获胜者的名字。
| 输入 | 输出 | 提示 |
|---|---|---|
| 3 1 2 3 4 5 6 |
Karen | 有 对整数满足条件: ,而 是一个偶数,所以 获胜。 |
| 5 2 4 6 8 10 9 7 5 3 1 |
Karen | 总共有 对整数满足条件,所以获胜者仍然是 。 |
把所有数字放到 中,然后 枚举所有的数对 。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#include <ctime>#include <functional>#include <iomanip>using namespace std;#define LL long longconst int maxn = 2000 + 100;int n;int a[maxn], b[maxn];set<int> st;int main() {#ifdef LOCALfreopen("test.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endifios::sync_with_stdio(false);scanf("%d", &n);for(int i = 1; i <= n; ++i) {scanf("%d", &a[i]);st.insert(a[i]);}for(int i = 1; i <= n; ++i) {scanf("%d", &b[i]);st.insert(b[i]);}int ans = 0;for(int i = 1; i <= n; ++i) {for(int j = 1; j <= n; ++j) {int Xor = a[i] ^ b[j];if(st.find(Xor) != st.end()) {++ans;}}}if(ans % 2 == 0) {printf("Karen\n");} else {printf("Koyomi\n");}return 0;}
计算 的个位数,其中 ,且 。
输入只包含两个整数 和 。
输出 的个位数。
| 输入 | 输出 | 提示 |
|---|---|---|
| 2 4 | 2 | ,个位数字是 。 |
| 0 10 | 0 | ,个位数是 。 |
| 107 109 | 2 | ,个位数字是 。 |
阶乘的个位经常是 ,可以发现,只要 和 之间的距离超过 , 的个位就是 (因为含有因子 和 )。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#include <ctime>#include <functional>#include <iomanip>using namespace std;#define LL long longLL a, b;int main() {#ifdef LOCALfreopen("test.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endifios::sync_with_stdio(false);scanf("%I64d%I64d", &a, &b);if(b - a > 5) {printf("0\n");} else {LL ans = 1;for(LL i = a + 1; i <= b; ++i) {ans *= i;ans %= 10;}printf("%I64d\n", ans);}return 0;}
有红、蓝、紫三种颜色的岛屿,岛屿数量分别为 ,要在岛屿之间建桥,每座桥的长度都为 ,问要使所有岛屿满足以下条件,总共有多少种桥的建法:
- 同一种颜色的任意两座岛屿之间的距离至少为 ;
- 每个岛屿的度最大为 。
输入包含三个整数 ,分别表示三种颜色的岛屿的数量。
输出合法的建桥的方案数对 取模后的结果。
| 输入 | 输出 | 提示 |
|---|---|---|
| 1 1 1 | 8 | 能在三个岛屿之间建立的桥有三个,且即使三座桥同时建立也是合法的,所以总共的合法的 方案数为 。 |
| 1 2 2 | 63 | 对于 的情况,下图中上面的两幅图是合法的建桥方案,下面的两幅图 不是合法的建桥方案: ![]() |
| 1 3 5 | 3264 | |
| 6 2 9 | 813023575 |
通过画样例可以发现,每座岛屿连出的两条边(桥)只能通向另外两种颜色的岛屿,对于任意两种颜色的岛屿 ,它们之间能连的边的数量为 ,可以从 中选出 个点与另一种颜色的 个点中的 连边,左右两边的点一一对应,总共有 种对应方式,所以方案数为 。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <climits>#include <cfloat>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <bitset>#include <algorithm>#include <ctime>#include <functional>#include <iomanip>using namespace std;#define LL long longconst int maxn = 5000 + 100;const LL MOD = 998244353LL;int a, b, c;LL ans;LL C[maxn][maxn];LL fac[maxn];void Init() {C[0][0] = 1;for(int i = 1; i <= 5000; ++i) {for(int j = 0; j <= i; ++j) {if(j == 0 || j == i) {C[i][j] = 1;} else {C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;}}}fac[0] = 1;for(int i = 1; i <= 5000; ++i) {fac[i] = (fac[i - 1] * i) % MOD;}}LL solve(int a, int b) {int Min = min(a, b);LL ret = 0;for(int i = 0; i <= Min; ++i) {ret = (ret + (((C[a][i] * C[b][i]) % MOD) * fac[i]) % MOD) % MOD;}return ret;}int main() {#ifdef LOCALfreopen("test.txt", "r", stdin);// freopen("out.txt", "w", stdout);#endifios::sync_with_stdio(false);Init();scanf("%d%d%d", &a, &b, &c);ans = solve(a, b);ans = (ans * solve(b, c)) % MOD;ans = (ans * solve(a, c)) % MOD;printf("%I64d\n", ans);return 0;}
在一个 的网格上,进行 次操作:
- :以在位置 和 上的两个方格为矩形的两个对角,画出矩形的边框,在矩形的边框上设置一圈障碍物;
- :以在位置 和 上的两个方格为矩形的两个对角,消去在这个矩形边框上的障碍物;
- :询问能否从位置 不穿过障碍地到达位置 。
第一行为三个整数 ,接下去 行每行 个整数 ,表示每次操作的方式与对应的坐标,其中 ,且
- 当 时,,数据保证每个矩形的边框不会出现相交、重叠的情况;
- 当 时,,数据保证每一个 中的坐标一定在之前的 中出现过;
- 当 时,没有额外的限制。
对于每次 的询问,如果可以不穿过障地从 到达 ,就输出 ,否则输出 。
| 输入 | 输出 | 提示 |
|---|---|---|
| 5 6 5 1 2 2 4 5 1 3 3 3 3 3 4 4 1 1 2 2 2 4 5 3 1 1 4 4 |
No Yes |
两次询问时的示意图如下:![]() |
| 2500 2500 8 1 549 1279 1263 2189 1 303 795 1888 2432 1 2227 622 2418 1161 3 771 2492 1335 1433 1 2017 2100 2408 2160 3 48 60 798 729 1 347 708 1868 792 3 1940 2080 377 1546 |
No Yes No |
先考虑一个更简单些的问题,如果每次操作 是将矩形区域上的所有数字都 ,每次操作 是 ,而操作 是询问两点上的值是否相等,就是一个二维树状数组的问题。现在再来思考这个问题,这两个问题其实是相似的,在题给问题中,对每个矩形编号,添加某个矩形的边框时将矩形区域内的数字都加上这个矩形的编号,删除某个矩形的边框时将矩形区域内的数字都减去这个矩形的编号。我们无法设计出一个编号方式使得对所有的矩形编号都不出现 ,只要出现这种情况,就会发生冲突,造成判断的结果出错,但是我们可以用随机编号的方式将这些编号求和出现冲突的概率降低,对每个新的矩形,将其编号为 ,就可以将冲突的概率降低到 。
#include <iostream>#include <cstdio>#include <cstdlib>#include <cmath>#include <sstream>#include <cstring>#include <string>#include <vector>#include <list>#include <queue>#include <stack>#include <map>#include <set>#include <algorithm>#include <ctime>using namespace std;#define LL long longconst int maxn = 2500 + 100;int n, m, q, t, r1, r2, c1, c2;int sum[maxn][maxn], num[maxn][maxn];int lowbit(int x) {return x & (-x);}void update(int i, int j, int x) {while(i <= n) {int jj = j;while(jj <= m) {sum[i][jj] += x;jj += lowbit(jj);}i += lowbit(i);}}int query(int i, int j) {int ret = 0;while(i > 0) {int jj = j;while(jj > 0) {ret += sum[i][jj];jj -= lowbit(jj);}i -= lowbit(i);}return ret;}int main() {#ifdef Dmaxiyafreopen("test.txt", "r", stdin);#endif // Dmaxiyaios::sync_with_stdio(false);srand((unsigned)time(NULL));while(scanf("%d%d%d", &n, &m, &q) != EOF) {memset(sum, 0, sizeof(sum));for(int i = 0; i < q; ++i) {scanf("%d%d%d%d%d", &t, &r1, &c1, &r2, &c2);int x;if(t == 1) {x = rand() * rand();num[r1][c1] = x;} else if(t == 2) {x = -num[r1][c1];}if(t != 3) {update(r1, c1, x);update(r1, c2 + 1, -x);update(r2 + 1, c1, -x);update(r2 + 1, c2 + 1, x);} else {int tmp1 = query(r1, c1);int tmp2 = query(r2, c2);if(tmp1 == tmp2) {printf("Yes\n");} else {printf("No\n");}}}}return 0;}