A - Divisible
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<i64>;
using pii = pair<int, int>;
using piii = tuple<int, int, int>;
const int inf = 1e18;
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n , k;
cin >> n >> k;
for( int i = 1 , x ; i <= n ; i ++ ){
cin >> x;
if( x % k == 0 ) cout << x / k << " ";
}
return 0;
}
B - Substring
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<i64>;
using pii = pair<int, int>;
using piii = tuple<int, int, int>;
const int inf = 1e18;
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
string s;
cin >> s;
set<string> cnt;
for (int i = 0; i < s.size(); i++)
for (int j = 1; i + j <= s.size(); j++)
cnt.insert(s.substr(i, j));
cout << cnt.size() << "\n";
return 0;
}
C - Ideal Holidays
首先要做一個取模,然後列舉取模後所有的點做起點,判斷能不能把所有的工作都安排在假期。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<i64>;
using pii = pair<int, int>;
using piii = tuple<int, int, int>;
const int inf = 1e18;
i32 main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, a, b;
cin >> n >> a >> b;
b += a;
vi d(n);
for (auto &i: d) {
cin >> i, i = (i - 1) % b;
}
set<int> c;
for (auto i: d)
c.insert(i);
if( c.size() == 1 ){
cout << "Yes\n";
return 0;
}
while (true) {
int x = *c.begin();
if (x >= b) break;
c.erase(c.begin());
if (*c.rbegin() < x + a) {
cout << "Yes\n";
return 0;
}
c.insert(x + b);
}
cout << "No\n";
return 0;
}
D - Popcount and XOR
首先我們統計出\(popcpunt(C) = t\)。然後我們\(X,Y\)異或能得到的數的一的數量的範圍是\([abs(X-Y) , X + Y]\),判斷\(t\)是否在這個範圍內。
然後我們設抵消的一的個數有\(x\)個,則題目可知$a + b - 2*x = t \(,則\)a + b + t = 2t - 2 * x \(,所以\)a+b+t\(一定是偶數,並且\)\frac{a + b + 2 }{ 2} = t - x $,根據題目可知\(0\le \frac {a+b+t}{2} \le 60\)恆成立。
然後我們算出\(x\)的值,開始一位位的遍歷\(C\)即可,每一位的值如果是0,就可以給兩個兩個數這一位賦值為 1,如果是 1 就可以跟任意一個數賦值為 1.
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<i64>;
using pii = pair<int, int>;
using piii = tuple<int, int, int>;
using node = bitset<60>;
const int N = (1ll << 60);
i32 main() {
int a, b, c;
cin >> a >> b >> c;
node C(c);
int t = C.count();
if (a + b < t or t < abs(a - b) or (a + b + t) % 2 != 0 or (a + b + t) / 2 > 60) {
cout << "-1\n";
return 0;
}
t = (a + b - t) / 2, a -= t, b -= t;
int x = 0, y = 0;
for (int i = 59; i >= 0; i--) {
x <<= 1, y <<= 1;
if (C[i]) {
if (a > 0) x |= 1, a--;
else if (b > 0) y |= 1, b--;
} else {
if (t > 0) x |= 1, y |= 1, t--;
}
}
cout << x << " " << y << "\n";
return 0;
}
E - Set Add Query
用set
模擬出這個集合,並把第\(i\)次操作後set
的大小記為\(sum[i]\),並且統計出每個數字操作的位置。
對於每個數字,實際上就是奇數次操作到偶數次操作中間的部分,這一部分可以用字首和快速求出來。
#include <bits/stdc++.h>
using namespace std;
using i32 = int32_t;
using i64 = long long;
#define int i64
using vi = vector<i64>;
using pii = pair<int, int>;
using piii = tuple<int, int, int>;
const int inf = 1e18;
i32 main() {
int n, q;
cin >> n >> q;
vector<vi> op(n + 1);
vi sum(q + 1);
set<int> s;
for (int i = 1, x; i <= q; i++) {
cin >> x;
if (s.count(x)) s.erase(x);
else s.insert(x);
sum[i] = sum[i - 1] + s.size();
op[x].push_back(i);
}
for (auto &it: op)
if (it.size() % 2 == 1) it.push_back(q + 1);
for (int i = 1, ans; i <= n; i++) {
ans = 0;
for (int j = 1; j < op[i].size(); j += 2)
ans += sum[op[i][j] - 1] - sum[op[i][j - 1] - 1];
cout << ans << " ";
}
return 0;
}