Codeforces Round 1003 (Div. 4)
A. Skibidus and Amog'u
按题意输出即可。
点击查看代码
void solve() {
std::string s;
std::cin >> s;
std::cout << s.substr(0, (int)s.size() - 2) + "i" << "\n";
}
B. Skibidus and Ohio
题意:给你一个字符串
如果没有一个位置满足,显然无法操作。如果至少有一个地方满足,那么因为可以随意变化
点击查看代码
void solve() {
std::string s;
std::cin >> s;
int n = s.size();
for (int i = n - 1; i > 0; -- i) {
if (s[i] == s[i - 1]) {
std::cout << 1 << "\n";
return;
}
}
std::cout << n << "\n";
}
C1. Skibidus and Fanum Tax (easy version) && C2. Skibidus and Fanum Tax (hard version)
题意:给你两个数组
从后往前做,每个数都应该在不超过后一个数的同时尽可能大,设
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector<int> a(n), b(m);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
for (int i = 0; i < m; ++ i) {
std::cin >> b[i];
}
std::sort(b.begin(), b.end());
if (b.back() - a[n - 1] > a[n - 1]) {
a[n - 1] = b.back() - a[n - 1];
}
for (int i = n - 2; i >= 0; -- i) {
int j = std::upper_bound(b.begin(), b.end(), a[i] + a[i + 1]) - b.begin() - 1;
if (j < 0) {
if (a[i] > a[i + 1]) {
std::cout << "NO\n";
return;
}
} else {
if (a[i] > a[i + 1] || b[j] - a[i] > a[i]) {
a[i] = b[j] - a[i];
}
}
}
std::cout << "YES\n";
}
D. Skibidus and Sigma
题意:给你
总和最大的出现在前面更优,因为它会被后面的每个位置做贡献,所以按照总和排序即可。
点击查看代码
void solve() {
int n, m;
std::cin >> n >> m;
std::vector a(n, std::vector<i64>(m + 1));
for (int i = 0; i < n; ++ i) {
for (int j = 1; j <= m; ++ j) {
std::cin >> a[i][j];
a[i][j] += a[i][j - 1];
}
}
std::sort(a.begin(), a.end(), [&](std::vector<i64> & a, std::vector<i64> & b) {
return a.back() > b.back();
});
i64 sum = 0, ans = 0;
for (int i = 0; i < n; ++ i) {
for (int j = m; j >= 1; -- j) {
a[i][j] -= a[i][j - 1];
}
for (int j = 1; j <= m; ++ j) {
sum += a[i][j];
ans += sum;
}
}
std::cout << ans << "\n";
}
E. Skibidus and Rizz
题意:构造一个01串,使得恰好有
如果
否则从个数多的开始,构造
点击查看代码
void solve() {
int n, m, k;
std::cin >> n >> m >> k;
if (k < std::abs(n - m) || k > std::max(n, m)) {
std::cout << -1 << "\n";
return;
}
std::string ans;
int i = (m > n);
while (n || m) {
if (i & 1) {
int t = std::min(k, m);
ans += std::string(t, '1');
m -= t;
} else {
int t = std::min(k, n);
ans += std::string(t, '0');
n -= t;
}
++ i;
}
std::cout << ans << "\n";
}
F. Skibidus and Slay
题意:求对于每个
因为
所以枚举每个点所有邻点,看有没有值相同的就行。
点击查看代码
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::vector<std::vector<int>> adj(n);
for (int i = 1; i < n; ++ i) {
int u, v;
std::cin >> u >> v;
-- u, -- v;
adj[u].push_back(v);
adj[v].push_back(u);
}
std::string s(n, '0');
for (int u = 0; u < n; ++ u) {
std::set<int> set;
set.insert(a[u]);
for (auto & v : adj[u]) {
if (set.count(a[v])) {
s[a[v] - 1] = '1';
}
set.insert(a[v]);
}
}
std::cout << s << "\n";
}
G. Skibidus and Capping
题意:给你一个数组
先预处理筛质数,然后跑出两个质数的乘积的数。
然后排序后从前往后看。如果当前数是质数,那么它要选一个不是它的质数配对。如果他是两个质数的乘积,则它要选这两个质数或者选它自己。如果两个都不是,则和任何数的
记录每个数的个数和质数的个数从前往后讨论即可。
点击查看代码
const int N = 2e5 + 5;
std::vector<int> primes;
bool st[N];
int f[N];
void init(int n) {
for (int i = 2; i <= n; ++ i) {
if (!st[i]) {
primes.push_back(i);
}
for (auto & p : primes) {
if (p * i > n) {
break;
}
st[p * i] = true;
if (i % p == 0) {
break;
}
}
}
for (int i = 0; i < primes.size(); ++ i) {
for (int j = i; j < primes.size(); ++ j) {
if ((i64)primes[i] * primes[j] > n) {
break;
}
f[primes[i] * primes[j]] = primes[i];
}
}
}
void solve() {
int n;
std::cin >> n;
std::vector<int> a(n);
for (int i = 0; i < n; ++ i) {
std::cin >> a[i];
}
std::sort(a.begin(), a.end());
i64 ans = 0, cntp = 0;
std::map<int, int> cnt;
for (int i = 0; i < n; ++ i) {
if (!st[a[i]]) {
ans += cntp - cnt[a[i]];
++ cntp;
} else if (f[a[i]]) {
if (a[i] / f[a[i]] == f[a[i]]) {
ans += cnt[f[a[i]]];
} else {
ans += cnt[f[a[i]]] + cnt[a[i] / f[a[i]]];
}
ans += cnt[a[i]] + 1;
}
cnt[a[i]] += 1;
// std::cout << ans << " \n"[i == n - 1];
}
std::cout << ans << "\n";
}
int main() {
std::ios::sync_with_stdio(false), std::cin.tie(0), std::cout.tie(0);
init(2e5);
int T = 1;
std::cin >> T;
//scanf("%d", &T);
while (T -- ) {
solve();
}
return 0;
}
H. Bro Thinks He's Him
题意:一个01串的价值为01段的个数,给你一个01串,求它的所有子串的价值之和。并且有
既然题目是单点修改,那么我们考虑每个点会贡献多少。
对于第
现在考虑修改后怎么更新贡献。首先按上面的讨论减去这个点单独的贡献,然后这个点还会对后面的贡献有影响,因为后面的点可能选它在前面。那么他会给后面贡献
然后更改后再按上面的讨论加回来就行。
点击查看代码
template <class T>
struct Fenwick {
int n;
std::vector<T> tr;
Fenwick(int _n) {
init(_n);
}
void init(int _n) {
n = _n;
tr.assign(_n + 1, T{});
}
void add(int x, const T &v) {
for (int i = x; i <= n; i += i & -i) {
tr[i] = tr[i] + v;
}
}
T query(int x) {
T res = 0;
for (int i = x; i; i -= i & -i) {
res = res + tr[i];
}
return res;
}
T sum(int l, int r) {
return query(r) - query(l - 1);
}
};
void solve() {
std::string s;
std::cin >> s;
int n = s.size();
std::vector<Z> p2(n + 1);
p2[0] = 1;
for (int i = 1; i <= n; ++ i) {
p2[i] = p2[i - 1] * 2;
}
Fenwick<Z> tr10(n), tr11(n), tr20(n), tr21(n);
Z ans = 0;
for (int i = 1; i <= n; ++ i) {
if (s[i - 1] == '1') {
ans += (tr10.query(i) + 1) * p2[n - i];
tr11.add(i, p2[i - 1]);
tr21.add(i, p2[n - i]);
} else {
ans += (tr11.query(i) + 1) * p2[n - i];
tr10.add(i, p2[i - 1]);
tr20.add(i, p2[n - i]);
}
}
auto get1 = [&](int i) -> Z {
if (s[i - 1] == '1') {
return (tr10.query(i) + 1) * p2[n - i];
} else {
return (tr11.query(i) + 1) * p2[n - i];
}
};
auto get2 = [&](int i) -> Z {
if (s[i - 1] == '1') {
return p2[i - 1] * tr20.sum(i, n);
} else {
return p2[i - 1] * tr21.sum(i, n);
}
};
int q;
std::cin >> q;
while (q -- ) {
int i;
std::cin >> i;
ans -= get1(i);
ans -= get2(i);
if (s[i - 1] == '1') {
tr11.add(i, -p2[i - 1]);
tr21.add(i, -p2[n - i]);
} else {
tr10.add(i, -p2[i - 1]);
tr20.add(i, -p2[n - i]);
}
s[i - 1] ^= 1;
if (s[i - 1] == '1') {
tr11.add(i, p2[i - 1]);
tr21.add(i, p2[n - i]);
} else {
tr10.add(i, p2[i - 1]);
tr20.add(i, p2[n - i]);
}
ans += get1(i);
ans += get2(i);
std::cout << ans << " \n"[!q];
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具