【RS十周年】比赛题解
Successful person
优先用大盒:先看 n 能否被 5 整除,若能,用 5 颗装盒子数最少,结果为 n / 5。
混合装尝试:若不能被 5 整除,看余数能否被 3 整除,能则用 5 颗装和 3 颗装组合。
逐步减 3 尝试:若上述都不满足,不断从 n 中减 3,每减一次检查剩余数量能否被 5 整除,能则计算总盒数。
若整个过程都没找到方案,输出 wwyytsn!,否则输出最少盒子数。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int result = -1;
if (n % 5 == 0) {
result = n / 5;
} else if ((n % 5) % 3 == 0) {
result = n / 5 + (n % 5) / 3;
} else {
int temp = n;
while (temp >= 3) {
temp -= 3;
if (temp % 5 == 0) {
result = temp / 5 + (n - temp) / 3;
break;
}
}
}
if (result == -1) {
cout << "wwyytsn!";
} else {
cout << result;
}
return 0;
}
迷魂阵
(本来有个更难的小模拟的,但是后面题有点爆了,所以这题想着节省一点时间的)
每个棋子走到对面需要
由于
代码1
#include <bits/stdc++.h>
using namespace std;
int main() {
long long n;
cin >> n;
long long ans = n * (2 * n - 1);
if (n & 1) cout << ans + 1 << endl;
else cout << ans << endl;
return 0;
}
代码2
#include <bits/stdc++.h>
#define LL long long
using namespace std;
LL n;
int main() {
cin >> n;
cout << 2 * n * (n - 1) + n + (n % 2);
return 0;
}
地心历险
算法一
注意到图是三部图,如果令
对于一个非根节点,显然可以通过父亲边调整权值。设
接下来考虑二分图的情况,重新给图染色(只用
算法二
上述算法中直接构造只有根可能出错,故当根不合法时,重新随机选择根和 dfs 生成树。注意到题目只要求值不同而不是上面提到的模
#include <bits/stdc++.h>
#define pb push_back
#define pf push_front
#define mp make_pair
using namespace std;
template <typename T>
void read(T &x) {
T flag = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') flag = -1;
for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
x *= flag;
}
const int maxn = 200005;
struct e{
int u, v, val;
}ans[maxn];
int n, m;
char s[maxn];
int col[maxn], f[maxn], val[maxn], d[maxn];
vector<pair<int, int>> vec[maxn], t[maxn];
bool vis[maxn];
int tmp[maxn];
int flag, End;
int pre[maxn], num[maxn];
void dfs(int x, int fa, int id) {
f[x] = fa;
if (fa) t[x].pb(mp(fa, id));
for (int i = 0; i < (int)vec[x].size(); i++) {
int y = vec[x][i].first;
if (f[y] > 0 || y == flag) continue;
t[x].pb(mp(y, vec[x][i].second));
dfs(y, x, vec[x][i].second);
}
}
void get_ans(int x) {
for (int i = 0; i < (int)t[x].size(); i++) {
int y = t[x][i].first;
if (y == f[x]) continue;
get_ans(y);
int m = col[y] - d[y];
ans[t[x][i].second].val = m;
d[y] = d[y] + m;
d[x] = d[x] + m;
}
}
void get_ans2(int x) {
for (int i = 0; i < (int)t[x].size(); i++) {
int y = t[x][i].first;
if (y == f[x]) continue;
get_ans2(y);
int m = tmp[y] - d[y];
ans[t[x][i].second].val = m;
d[y] = d[y] + m;
d[x] = d[x] + m;
}
}
void check(int x) {
for (int i = 0; i < (int)vec[x].size(); i++) {
int y = vec[x][i].first;
if (tmp[y] == -1) tmp[y] = tmp[x] ^ 1, check(y);
else {
if (tmp[y] == tmp[x]) {
flag = x;// 不是二分图
}
}
}
}
void yyy(int x) {
for (int i =0; i < (int)vec[x].size(); i++) {
int y = vec[x][i].first;
if (tmp[y] != -1) continue;
tmp[y] = tmp[x] ^ 1;
yyy(y);
}
}
int cnt[maxn];
void output() {
for (int i = 1; i <= m; i++) {
ans[i].val = (ans[i].val % 3 + 3) % 3;
if (ans[i].val == 0) ans[i].val = 3;
printf("%d\n", ans[i].val);
cnt[ans[i].u] += ans[i].val;
cnt[ans[i].v] += ans[i].val;
}
}
void jjj(int x) {
for (int i = 0; i < (int)vec[x].size(); i++) {
int y = vec[x][i].first;
if (tmp[y] == -1) tmp[y] = tmp[x] ^ 1, pre[y] = x, num[y] = vec[x][i].second, jjj(y);
else {
if (y == flag && tmp[x] == tmp[flag]) {
End = x;
}
}
}
}
void work() {
tmp[1] = 0;
check(1);
if (flag) {// 不是二分图
dfs(flag, 0, 0);
get_ans(flag);
int m = (col[flag] - d[flag]);
memset(tmp, -1, sizeof(tmp));
tmp[flag] = 0;
jjj(flag);
for (int i = End; i != flag; i = pre[i]) {
ans[num[i]].val += m;
m = -m;
}
for (int i = 0; i < (int)vec[End].size(); i++) {
if (vec[End][i].first == flag) ans[vec[End][i].second].val += m << 1;
}
output();
} else {
flag = 1;
memset(tmp, -1, sizeof(tmp));
tmp[1] = 0;
yyy(flag);
dfs(flag, 0, 0);
get_ans2(flag);
if ((d[1] % 3 + 3) % 3 == 1 && vec[1].size() > 1) {
ans[vec[1][1].second].val++; ans[vec[1][2].second].val++;
}
output();
}
}
int main() {
memset(tmp, -1, sizeof(tmp));
read(n); read(m);
for (int i = 1; i <= n; i++) {
read(col[i]);
}
for (int i = 1; i <= m; i++) {
int u, v;
read(u); read(v);
ans[i].u = u; ans[i].v = v;
vec[u].pb(mp(v, i));
vec[v].pb(mp(u, i));
}
for (int i = 1; i <= n; i++) reverse(vec[i].begin(), vec[i].end());
work();
return 0;
}
魔法屋
发现
的值。记
记
其中
而答案即为 太懒了脑子不够用了。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e7 + 5, mod = 1e9 + 7;
template <typename T>
void read(T &x) {
T sgn = 1;
char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;
for (x = 0; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
x *= sgn;
}
int n, a[maxn], x, y, k, m, ans, cnt[maxn];
int f[20][720721], g[20][720721], pw[20], q;
int qmod(int x) { return x >= mod ? x - mod : x; }
int ksm(int a, int b = mod - 2) { int ret = 1; for (; b; b >>= 1, a = 1ll * a * a % mod) if (b & 1) ret = 1ll * ret * a % mod; return ret; }
int main() {
int lcm = 1;
for (int i = 1; i <= 16; i++) lcm = lcm * i / __gcd(lcm, i);
read(n); read(k);
for (int i = 1; i <= n; i++) read(a[i]);
pw[0] = 1;
for (int i = 1; i <= k; i++) pw[i] = 1ll * pw[i - 1] * n % mod;
for (int i = 1; i <= n; i++)
cnt[a[i] % lcm]++, ans = qmod(ans + 1ll * (a[i] / lcm * lcm) * pw[k - 1] % mod * k % mod);
for (int i = 0; i < lcm; i++) g[k + 1][i] = 1;
for (int i = k; i; i--)
{
for (int j = 0; j < lcm; j++)
{
f[i][j] = qmod(1ll * (n - 1) * f[i + 1][j] % mod + f[i][j]);
f[i][j] = qmod(qmod(1ll * j * g[i + 1][j - j % i] % mod + f[i + 1][j - j % i]) + f[i][j]);
g[i][j] = qmod(1ll * (n - 1) * g[i + 1][j] % mod + g[i + 1][j - j % i]);
}
}
for (int i = 0; i < lcm; i++) ans = qmod(ans + 1ll * cnt[i] * f[1][i] % mod);
printf("%d\n", ans);
read(q);
while (q--) {
int x, y;
read(x); read(y);
ans = qmod(ans - 1ll * (a[x] / lcm * lcm) * pw[k - 1] % mod * k % mod + mod);
ans = qmod(ans - f[1][a[x] % lcm] + mod);
a[x] = y;
ans = qmod(ans + 1ll * (a[x] / lcm * lcm) * pw[k - 1] % mod * k % mod);
ans = qmod(ans + f[1][a[x] % lcm]);
printf("%d\n", ans);
}
return 0;
}