Codeforces Round #685 (Div. 2)
A - Subtract or Divide
枚举
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; int ans = 0;
if (n == 1) cout << 0 << '\n';
else if (n == 2) cout << 1 << '\n';
else if (n == 3) cout << 2 << '\n';
else if (n & 1) cout << 3 << '\n';
else cout << 2 << '\n';
}
return 0;
}
B - Non-Substring Subsequence
找一下区间的前面或者后面又没有 s[l] / s[r] 即可
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n >> m;
string s; cin >> s;
vector<PII> v(n, { 0, 0 }), ve(n, { 0, 0 });
rep (i, 1, n - 1) {
v[i] = v[i - 1];
if (s[i - 1] == '0') v[i].fi = 1;
else v[i].se = 1;
ve[n - i - 1] = ve[n - i];
if (s[n - i] == '0') ve[n - i - 1].fi = 1;
else ve[n - i - 1].se = 1;
}
rep (i, 1, m) {
int l, r; cin >> l >> r; --l, --r;
bool f = 0;
if (s[l] == '0' && v[l].fi) f = 1;
else if (s[l] == '1' && v[l].se) f = 1;
else if (s[r] == '0' && ve[r].fi) f = 1;
else if (s[r] == '1' && ve[r].se) f = 1;
if (f) cout << "YES\n";
else cout << "NO\n";
}
}
return 0;
}
C - String Equality
模拟
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n >> k;
string s, t; cin >> s >> t;
rep (i, 0, 25) a[i] = b[i] = 0;
for (auto i : s) ++a[i - 'a'];
for (auto i : t) ++b[i - 'a'];
rep (i, 0, 24)
if (a[i] > b[i]) {
int t = (a[i] - b[i]) / k * k;
a[i] -= t; a[i + 1] += t;
}
bool f = 1;
rep (i, 0, 25) if (a[i] != b[i]) { f = 0; break; }
cout << (f ? "YES\n" : "NO\n");
}
return 0;
}
D - Circle Game
博弈, 先化简一下
先假设 x轴, 走了 x 步, y轴走了 y步
则 \(x^2k^2 + y^2k^2 \leqslant d^2\) 即 \(x^2+ y^2 \leqslant \left \lfloor \frac{d^2}{k^2} \right \rfloor\)
因为贪心, 就先捡石子一样, 保证状态不变, 对手走一步 x 轴, 那我就走一步 y 轴, 保证关系不变
及当 x == y 时, 先手必输, abs(y - x) == 1 时, 先手必赢
int main() {
IOS;
for (cin >> _; _; --_) {
ll n, m; cin >> n >> m;
if (n == 1) { cout << "Ashish\n"; continue; }
n = sqr(n) / sqr(m), m = sqrt(n >> 1);
if (sqr(m) + sqr(m + 1) <= n) cout << "Ashish\n";
else cout << "Utkarsh\n";
}
return 0;
}
E1 & E2 Bitwise Queries (Hard Version)
我们注意到这是 2 的次方, 就应该意识到, 线性基必定在 [0, \(2^x\) - 1] 内
直接让 得到 \(a[i] = x_1 ^ x_i\), 这样只要我们知道 任何一个 \(x_i\), 整个序列我们都知道了
如果存在 a[i] == a[j] 代表有两个数相等(a[i] == 0, 代表 \(x_1\) 和 \(x_i\) 相等), 直接 得到 \(x_i = x_j = x_i & x_j\), n 次出答案
不过不存在, 则说明这个序列[0, \(2^x\) - 1] 每个数都出现了一次, 则必存在 a[i] == 1, 及 \(abs(x_1 - x_i) == 1\),
所以 \(x_1, x_i 分别是 x_1 & x_i, x_1 & x_i ^ 1\), 我们现在想知道 a[1], 就是要知道 a[1] 的奇偶性
找到序列中任意一个 a[j] & 1 == 0, 即可, 代表 \(x_1 和 x_j\) 的奇偶性相同, 直接 &, 就知道a[1]的奇偶性了, a[1] get!!, n + 1次出答案
const int N = 65536 + 5;
int n, m, _, k;
ll a[N];
map<int, int> st;
int main() {
IOS; cin >> n;
int x = 0, y, t = log2(n) - 1;
rep (i, 2, n) {
cout << "XOR " << 1 << ' ' << i << endl;
cin >> a[i];
if (a[i] == 0 && !x) {
cout << "AND " << 1 << ' ' << i << endl;
cin >> y; x = i;
} else if (st[a[i]] && !x) {
cout << "AND " << st[a[i]] << ' ' << i << endl;
cin >> y; x = i;
}
st[a[i]] = i;
}
if (x) a[1] = a[x] ^ y;
else {
cout << "AND " << 1 << ' ' << st[1] << endl;
cin >> a[1];
for (auto it : st) {
if (it.fi & 1) continue;
cout << "AND " << 1 << ' ' << it.se << endl;
int c; cin >> c;
if (c & 1) a[1] ^= 1;
break;
}
}
cout << "! " << a[1];
rep (i, 2, n) cout << ' ' << (a[i] ^ a[1]);
return 0;
}