比赛链接:
https://ac.nowcoder.com/acm/contest/38727
E.Everyone is bot
题意:
有 \(n\) 个人在群里复读,第 \(i\) 个人在第 \(j\) 个复读会获得 \(a_{i, j}\) 瓶冰红茶。
一次复读的过程如下:
每一轮按照编号从小到大的顺序,每一个人可以选择复读或者不复读,如果一个人在前面几轮复读过了,他不能再复读了。如果某一轮没有人选择复读,那么这次复读结束。
如果某个人是所有复读的人中倒数第 \(p\) 个复读的,那么他会被禁言,无法获得冰红茶,同时要倒付 154 瓶冰红茶。
每个人都想获得更多的冰红茶,问一次复读过后,每个人最多能获得多少冰红茶。
思路:
当有 \(n - p\) 个人已经复读了,那么最后 \(p\) 个人会互相牵制,谁也不想做倒数第 \(p\) 个,同理在这之前的 \(p\) 个人也会互相牵制,所以最后的答案就是前 \(n\) % \(p\) 个人能获得冰红茶。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
ios::sync_with_stdio(false);cin.tie(0);
LL n, p;
cin >> n >> p;
vector a(n + 1, vector<LL>(n + 1));
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
cin >> a[i][j];
for (int i = 1; i <= n; i ++ ){
if (i <= n % p) cout << a[i][i];
else cout << 0;
cout << " \n"[i == n];
}
return 0;
}
H.Here is an Easy Problem of Zero-chan
题意:
给定一棵 \(n\) 个节点的树,\(q\) 次询问,每次给定一个 \(x\),求 \(\prod_{i = 1}^{n} lca(x, i)\) 的后缀零的数量。
思路:
一个数的后缀零其实就是它分解之后有多少个 10,也等价于分解后 2 和 5 的数量中的小的那个值。
记节点 \(u\) 分解后 2 的数量为 \(cnt_2\),5 的数量为 \(cnt_5\),子树大小为 \(sz_u\)。
对于 \(u\),它及自己的子树节点的 \(lca\) 都是自己,所以 2 的贡献就是 \(sz_u * cnt_2\),5 的贡献同理。
接下来考虑剩余的节点,从 \(u\) 到根节点的路径上,\(u\) 与这些节点的 \(lca\) 都是它们自己,同时 \(u\) 与它们的其它分支上的子树节点的 \(lca\) 也是它们自己。
记节点 \(u\) 除子树外其它节点总和的 \(lca\) 分解后的 2 的数量为 \(pre_2\)。
对于子节点 \(v\),\(pre2_v = pre2_u + (sz_u - sz_v) * cnt2_u\)。
前一部分计算的是红色以上的数量,后一部分计算的是蓝色部分的数量。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
ios::sync_with_stdio(false);cin.tie(0);
LL n, q;
cin >> n >> q;
vector < vector <LL> > e(n + 1);
for (int i = 0; i < n - 1 ; i ++ ){
LL u, v;
cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
vector <LL> cnt2(n + 1), cnt5(n + 1), sum2(n + 1), sum5(n + 1), sz(n + 1);
function<void(LL, LL)> dfs1 = [&](LL u, LL fa){
sz[u] = 1;
LL t = u;
while(t % 2 == 0){
t /= 2;
cnt2[u] ++ ;
}
t = u;
while(t % 5 == 0){
t /= 5;
cnt5[u] ++ ;
}
for (auto v : e[u]){
if (v == fa) continue;
dfs1(v, u);
sz[u] += sz[v];
}
sum2[u] = cnt2[u] * sz[u];
sum5[u] = cnt5[u] * sz[u];
};
dfs1(1, 0);
vector <LL> pre2(n + 1), pre5(n + 1);
function<void(LL, LL)> dfs2 = [&](LL u, LL fa){
for (auto v : e[u]){
if (v == fa) continue;
pre2[v] += pre2[u] + (sz[u] - sz[v]) * cnt2[u];
pre5[v] += pre5[u] + (sz[u] - sz[v]) * cnt5[u];
dfs2(v, u);
}
};
dfs2(1, 0);
while(q -- ){
LL x;
cin >> x;
cout << min(sum2[x] + pre2[x], sum5[x] + pre5[x]) << "\n";
}
return 0;
}
J.Jellyfish and its dream
题意:
长为 \(n\) 的序列,值域为 0 ~ 2,如果 \((a_i + 1)\) mod 3 = \(a_{(i + 1) \% n}\),可以让 \(a_i = (a_i + 1)\) mod 3。问能否经过操作使得所有元素相等。
思路:
先对数组做一个差分。
差分后,一次操作可以让 (2, 1) 变成 (0, 0),(1, 1) 变成 (2, 0),(0, 1) 变成 (1, 0)。
所以 0 是没用的,只需要考虑 1 和 2 的数量,只要 1 的数量 >= 2 即可,让 2 和 1 相消。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
void solve(){
LL n;
cin >> n;
vector <LL> a(n);
for (int i = 0; i < n; i ++ )
cin >> a[i];
vector <LL> cnt(3);
for (int i = 0; i < n; i ++ ){
LL x = (a[i] - a[(i - 1 + n) % n] + 3) % 3;
cnt[x] ++ ;
}
if (cnt[1] >= cnt[2]) cout << "Yes\n";
else cout << "No\n";
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);
LL T = 1;
cin >> T;
while(T -- ){
solve();
}
return 0;
}
M.Maimai DX 2077
题意:
有四种类型的音符,每个音符有五种判定,每个音符的每一种判定都有一个标准分,只有 \(break\) 音符有额外分。
\(A\) 为所有判定都是 c.p 的标准分,\(A_0\) 为自己真实获得的标准分。
\(B\) 为所有判定都是 c.p 的额外分,\(B_0\) 为自己真实获得的额外分。
输出 \(\frac{A}{A_0} + \frac{B}{B_0} * 0.01\)。
思路:
直接模拟就行。
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);cin.tie(0);
cout << fixed << setprecision(15);
vector c(4, vector <int>(5));
for (int i = 0; i < 4; i ++ )
for (int j = 0; j < 5; j ++ )
cin >> c[i][j];
double A = 0, A0 = 0;
A0 = c[0][0] + c[0][1] + 0.8 * c[0][2] + 0.5 * c[0][3];
A = c[0][0] + c[0][1] + c[0][2] + c[0][3] + c[0][4];
A0 += 2 * (c[1][0] + c[1][1]) + 1.6 * c[1][2] + c[1][3];
A += 2 * (c[1][0] + c[1][1] + c[1][2] + c[1][3] + c[1][4]);
A0 += 3 * (c[2][0] + c[2][1]) + 2.4 * c[2][2] + 1.5 * c[2][3];
A += 3 * (c[2][0] + c[2][1] + c[2][2] + c[2][3] + c[2][4]);
A0 += 5 *(c[3][0] + c[3][1]) + 2.5 * c[3][2] + 2 * c[3][3];
A += 5 * (c[3][0] + c[3][1] + c[3][2] + c[3][3] + c[3][4]);
double B = 0, B0 = 0;
B0 = c[3][0] + 0.5 * c[3][1] + 0.4 * c[3][2] + 0.3 * c[3][3];
B = c[3][0] + c[3][1] + c[3][2] + c[3][3] + c[3][4];
cout << A0 / A * 100 + B0 / B << "\n";
return 0;
}
标签:sz,int,蔚来,LL,多校,cin,vector,加赛,复读
From: https://www.cnblogs.com/Hamine/p/16612830.html