Codeforces Global Round 27

写在前面

比赛地址:https://codeforces.com/contest/2035

前期犯唐 C 不会呃呃,后面 E 会了然而跑去写什么狗屁三分似掉了也没救回来。

本来想着一场上橙的,这下又掉分了哈哈。

厌学中。

A 签到

发现受到影响的位置仅有三种:

  • 在第 r 行,c+1m 列的,左移一位;
  • 在第 r+1n 行,第 1 列的,移动到上一行最后;
  • 在第 r+1n 行,第 2m 列的,左移一位。

三种位置的贡献求和即可。

复制复制
//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
//freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
int n, m, r, c; std::cin >> n >> m >> r >> c;
LL ans = 0;
ans += 1ll * (m - c);
ans += 1ll * (n - r) * (m - 1 + 1);
ans += 1ll * (n - r) * 1 * (m - 1);
std::cout << ans << "\n";
}
return 0;
}

B 结论

显然仅需考虑模 66 为 0。

一个显然的想法是先构造为全 3 的数,然后把某些位改成 6。

打了个表发现对于全 3 的数,模 66 的余数只有 3 和 33 两种情况,于是根据样例:

  • 若余数为 33,考虑再加 33,即将后两位改成 6 即可;
  • 若余数为 3,考虑再加 3033 即可。

若无法加则无解。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
//=============================================================
//=============================================================
//=============================================================
int main() {
//freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
int n; std::cin >> n;
std::string ans;
LL sum = 0;
for (int i = 1; i <= n; ++ i) ans.push_back('3'), sum = (10 * sum + 3) % 66;
if (sum == 33) {
ans[n - 1] = '6', ans[n - 2] = '6';
} else {
if (n == 1 || n == 3) ans = "-1";
else ans[n - 1] = '6', ans[n - 2] = '6', ans[n - 4] = '6';
}
std::cout << ans << "\n";
}
return 0;
}

C 构造

妈的不会构造被鲨了。

首先通过样例猜测,当 n 为奇数时 k=nn 为偶数时 k=2log2n+11,即两种情况都能取到上界。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, ans[kN];
LL k;
//=============================================================
void check() {
int temp = 0;
for (int i = 1; i <= n; ++ i) {
if (i % 2 == 0) temp |= ans[i];
else temp &= ans[i];
}
std::cout << "---" << temp << "\n";
}
//=============================================================
int main() {
// freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
std::cin >> n;
if (n & 1) {
k = n;
ans[n] = n;
ans[n - 1] = n - 1;
ans[n - 2] = 1;
for (int i = 1; i <= n - 3; ++ i) ans[i] = i + 1;
} else {
k = (1ll << (((LL) log2(n)) + 1)) - 1l;
std::map<int, bool> vis;
std::vector<int> b[2];
int len = n;
ans[n] = n;
ans[n - 1] = k ^ n;
if ((k ^ n) == 1) {
len = 2;
} else {
len = 4;
ans[n - 2] = ans[n - 1] - 1;
ans[n - 3] = 1;
}
for (int i = n - len + 1; i <= n; ++ i) vis[ans[i]] = 1;
for (int i = 1; i <= n; ++ i) if (!vis[i]) b[i % 2].push_back(i);
for (int i = 1, j = 0; i <= n - len; ++ i, j ^= 1) ans[i] = b[j].back(), b[j].pop_back();
}
// check();
std::cout << k << "\n";
for (int i = 1; i <= n; ++ i) std::cout << ans[i] << " ";
std::cout << "\n";
}
return 0;
}

D 贪心,单调栈

先把每个数 2 的因子的次数 cnti 求出来,记 ai 除掉所有 2 的因子后剩下的部分为 bi

发现前缀 1i 的最优操作方案,一定是将前缀 1i1 的操作方案中,某些位置的 2 的因子全部贡献给 ai 得到的。显然只要 bjai=2cnti×bi 就应当产生贡献,又发现一个位置只能向其他位置贡献一次,于是考虑单调栈维护当前有哪些位置能向之后产生贡献,每次加入一个数 ai 时不断弹栈将贡献给到 ai 即可。

注意上述判断条件 bj2cnti×bi 中,当 ai 获得了若干 2 的幂后会变得很大,因此需要单独写个比较函数,特判 cnti 较大时直接返回结果即可。

还需要写个快速幂,总时间复杂度 O(nlogv) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
const LL p = 1e9 + 7;
//=============================================================
int n;
LL cnt2[kN], a[kN], b[kN], pw2[kN];
int top, st[kN];
//=============================================================
LL qpow(LL x_, LL y_) {
LL ret = 1;
while (y_) {
if (y_ & 1) ret = ret * x_ % p;
x_ = x_ * x_ % p, y_ >>= 1ll;
}
return ret;
}
bool cmp(int p1_, int p2_) {
if (pw2[p2_] > 30) return 1;
return (1ll << pw2[p2_]) * b[p2_] >= b[p1_];
}
//=============================================================
int main() {
// freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
std::cin >> n;
for (int i = 1; i <= n; ++ i) cnt2[i] = 0;
for (int i = 1; i <= n; ++ i) std::cin >> a[i], b[i] = a[i];
for (int i = 1; i <= n; ++ i) {
while (b[i] % 2 == 0) ++ cnt2[i], b[i] /= 2;
}
top = 0;
LL ans = 0;
for (int i = 1; i <= n; ++ i) {
ans += b[i];
pw2[i] = cnt2[i];
while (top && cmp(st[top], i)) {
pw2[i] += pw2[st[top]];
ans -= b[st[top]] * (qpow(2, pw2[st[top]]) - 1 + p) % p;
ans = (ans + p) % p;
pw2[st[top]] = 0;
-- top;
}
st[++ top] = i;
ans += b[i] * (qpow(2, pw2[i]) - 1 + p) % p;
ans %= p;
std::cout << ans << " ";
}
std::cout << "\n";
}
return 0;
}

E 结论,数论分块

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const LL kInf = 1e18 + 2077;
//=============================================================
LL x, y, z, k, ans;
//=============================================================
void check(LL r_, LL c1_, LL d1_) {
LL c2 = kInf;
for (LL r = r_ * k + k, l; r > r_ * k; r = l - 1) {
l = std::max(r_ * k + 1, (LL) ceil(1.0 * (z - d1_) / ceil(1.0 * (z - d1_) / r)));
c2 = std::min(c2, x * (l - r_ * k) + y * ((LL) ceil(1.0 * (z - d1_) / l)));
}
ans = std::min(ans, c1_ + c2);
}
//=============================================================
int main() {
// freopen("1.txt", "r", stdin);
std::ios::sync_with_stdio(0), std::cin.tie(0);
int T; std::cin >> T;
while (T --) {
std::cin >> x >> y >> z >> k;
ans = kInf;
for (LL round = 0; ; ++ round) {
LL c1 = round * (k * x + y);
LL d1 = round * (round + 1ll) / 2ll * k;
if (d1 >= z) {
ans = std::min(ans, c1);
break;
}
check(round, c1, d1);
}
std::cout << ans << "\n";
}
return 0;
}

写在最后

怎么一堆思维结论题+打表,把我这种没脑子的呆瓜鲨了。

好想死掉。

posted @   Luckyblock  阅读(166)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示