Codeforces Round #736 (Div. 2)A~D
汪汪队掉大分
A. Gregor and Cryptography
脑筋急转弯题,输入的数 p 一定是质数,要求 P mod a = P mod b,输出 a b。那其实就只需要输出 2 和 p - 1 就可以了
注意:要求输出格式 2 ≤ a < b ≤P,眼瞎没看见 wa 了两发,可恶
#include <bits/stdc++.h>
using namespace std;
long long t, n;
int main() {
cin >> t;
for (int i = 1; i <= t; i++) {
cin >> n;
cout << 2 << " " << n - 1 << endl;
}
return 0;
}
B. Gregor and the Pawn Game
我宣布我就是个傻x,这题罚时上天,直接 room 同等过题数的人里妥妥垫底。而且以后我不用快读了,一开始 TLE 了两发,cin 加速 yyds
直接上代码吧,看看还是挺好理解的
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 10;
int t, n, ans;
char s1[maxn], s2[maxn];
bool vis[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
for (int _ = 1; _ <= t; _++) {
cin >> n;
cin >> s1 + 1;
cin >> s2 + 1;
fill(vis, vis + 1 + n, 0);
ans = 0;
for (int i = 1; i <= n; i++) {
if (s2[i] == '1') {
if (s1[i] == '0' && vis[i] == 0) {
vis[i] = true;
ans++;
}
else if (i - 1 >= 1 && vis[i - 1] == 0 && s1[i - 1] == '1') {
vis[i - 1] = true;
ans++;
}
else if (i + 1 <= n && vis[i + 1] == 0 && s1[i + 1] == '1') {
vis[i + 1] = true;
ans++;
}
}
}
cout << ans << endl;
}
return 0;
}
C. Web of Lies
- 传送门:C. Web of Lies
人被杀就会死,一个人会被杀的充要条件是跟比他大的数有边相连,所以只需要开一个数组维护就可以了
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e7 + 10;
int n, m, u, v, t, op, sum;
int cnt[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= m; i++) {
cin >> u >> v;
cnt[min(u, v)]++;
if (cnt[min(u, v)] == 1) sum++;
}
cin >> t;
while (t--) {
cin >> op;
if (op == 1) {
cin >> u >> v;
cnt[min(u, v)]++;
if (cnt[min(u, v)] == 1) sum++;
}
else if (op == 2) {
cin >> u >> v;
cnt[min(u, v)]--;
if (cnt[min(u, v)] == 0) sum--;
}
else {
printf("%d\n", n - sum);
}
}
return 0;
}
D. Integers Have Friends
我们另 d[i] = abs(a[i + 1] - a[i]),得到了长度为 n - 1 的数组 d。易得到 a[i ... j] 是一个 friend group 当且仅当 gcd(d[i … j − 1]) > 1。
题目就演变成了一个区间 gcd 问题,用线段树维护
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 2e5 + 10;
int t, n;
ll a[maxn], d[maxn];
struct node{
int l, r;
ll sum;
}tree[maxn * 3];
inline ll gcd(ll a, ll b) {
if (a % b == 0) return b;
else return gcd(b, a % b);
}
inline void build(int x, int l, int r) {
tree[x].l = l; tree[x].r = r;
if (l == r) {
tree[x].sum = d[l];
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
tree[x].sum = gcd(tree[x << 1].sum, tree[x << 1 | 1].sum);
}
inline ll query(int x, int l, int r) {
int ls = tree[x].l, rs = tree[x].r;
if (ls >= l && rs <= r) return tree[x].sum;
int mid = (ls + rs) >> 1;
ll ans = 1;
if (l <= mid) ans = query(x << 1, l, r);
if (r > mid) {
if (l <= mid) ans = gcd(ans, query(x << 1 | 1, l ,r));
else ans = query(x << 1 | 1, l, r);
}
return ans;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> t;
while (t--) {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (i > 1) d[i - 1] = abs(a[i] - a[i - 1]);
}
if (n == 1) {
cout << 1 << endl;
continue;
}
build(1, 1, n - 1);
int l = 1, r = 1;
int ans = 0;
while (r <= n - 1) {
ll now = query(1, l, r);
if (now > 1) {
ans = max(ans, r - l + 1);
r++;
}
else if (now == 1) {
l++; r++;
}
}
cout << ans + 1 << endl;
}
return 0;
}