蔚来杯2022牛客暑期多校训练营加赛 题解

E. Everyone is bot#

对于后 p 个人,这 p 个人相互制约,一旦有一个人进行复读,剩下的 p1 个人一定会进行复读,那么这个人就会被禁言,对于他来说不是最优策略。此时转移到 n=np 的情况继续讨论,一直讨论直至 np<p 时结束。此时前 np 个人只能按顺序复读,否则会被后面的人占位导致拿不到冰红茶。

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;

const int MAXN = 1000 + 5;

int n, p, a[MAXN][MAXN];

signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> p;
	for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) cin >> a[i][j];
	for(int i = 1; i <= n % p; i++) cout << a[i][i] << " ";
	for(int i = 1; i <= p * (n / p); i++) cout << "0 ";
	cout << "\n";
	return 0;
}

H. Here is an Easy Problem of Zero-chan#

由于 10=25,所以可将问题转化成对于每个 x,求 f[x]2 的因子个数和 5 的因子个数。

先对每个数进行质因子分解,设 x2 的因子个数和 5 的因子个数为 num2xnum5x

考虑树形dp,设子树大小为 szeuansf[u]2 的因子个数和 5 的因子个数,枚举到当前 u 时将 ans 分为两部分。

u 及其子树,这些节点和 u 求 lca 一定为 u,有 ans+=(num2u,num5u)szeu

u 的祖先 rt,这些节点和 u 求 lca 一定为 rt,有 ans+=(num2rt,num5rt)(szertszev),其中 vrt 的儿子且是 u 或者 u 的祖先,这部分在DFS的时候直接下传即可。

最后求得的 ans 两者取最小值即为答案。

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;

const int MAXN = 2e5 + 5;

int ans[MAXN], sze[MAXN], num2[MAXN], num5[MAXN], n, q;
vector<int> G[MAXN];

void DFS1(int u, int f) {
	sze[u] = 1;
	for(auto v : G[u]) {
		if(v == f) continue;
		DFS1(v, u);
		sze[u] += sze[v];
	}
}

void DFS2(int u, int f, int f2, int f5) {
	int u2 = num2[u] * sze[u] + f2, u5 = num5[u] * sze[u] + f5;
	ans[u] = min(u2, u5);
	for(auto v : G[u]) {
		if(v == f) continue;
		DFS2(v, u, f2 + (sze[u] - sze[v]) * num2[u], f5 + (sze[u] - sze[v]) * num5[u] );
	}
}

signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n >> q;
	for(int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		G[u].push_back(v);
		G[v].push_back(u);
	}
	for(int i = 1; i <= n; i++) {
		int cur = i;
		while(cur % 2 == 0) num2[i]++, cur /= 2;
		while(cur % 5 == 0) num5[i]++, cur /= 5;
	}
	DFS1(1, 0);
	DFS2(1, 0, 0, 0);
	while(q--) {
		int x; cin >> x;
		cout << ans[x] << "\n";
	}
	return 0;
}

J. Jellyfish and its dream#

首先将两个位置相邻的相等数合并起来,例如将 0,0,0,...,0 合并成 0

再将所有类似于 ...,0,1,2,0,1,... 的递增区间提取出来,并求出区间左右端点和区间内三个数的数量。

此时不被合并的区间类似于 [...,0,1,2][1,2,0,...],前一个区间的右端点值和后一个区间的左端点值相差为2。

对于此操作我们将后一个区间的左端点值+1,此时可以将两个区间进行合并。

断环成链,再进行区间合并操作,如果能得到一个长度大于等于 n 的区间则代表了有合法方案。

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define fi first
#define se second
#define pii pair<int, int>
//#define int long long
using namespace std;

const int MAXN = 2000000 + 5;

int n, N, cnt, sze, L[MAXN], a[MAXN], b[MAXN], sum[MAXN], rest[MAXN][5], pos[MAXN];
vector<pii> block;

bool Connect(int i, int j) {
	int need = a[ block[j].se ];
	return rest[i][need] > 0 && rest[i][(need - 1 + 3) % 3] > 0;
}

void Solve() {
	cin >> n; N = n;
	for(int i = 1; i <= n; i++) cin >> a[i], a[i + n] = a[i];
	n *= 2;	cnt = 0;
	for(int i = 1; i <= n; i++) if(i == n || a[i] != a[i + 1]) b[++cnt] = a[i], pos[cnt] = i;
	n = cnt;
	for(int i = 1; i <= cnt; i++) a[i] = b[i];
	block.clear(); block.push_back({1, 0});
	int sze = 0, flag = 0;
	for(int i = 2, l = 1, r = 1; i <= n + 1; i++) {
		if(i > n || a[i] != (a[i - 1] + 1) % 3) {
			block.push_back({r - l + 1, r}); ++sze;
			l = r = i;
		} else r = i;
	}
	
	for(int i = 1; i <= sze; i++) {
		L[i] = i; rest[i][0] = rest[i][1] = rest[i][2] = 0;
		for(int j = block[i].se - block[i].fi + 1; j <= block[i].se; j++) rest[i][ a[j] ]++;
		while( L[i] > 1 && Connect(i, L[i] - 1) ) {
			int need = a[ block[ L[i] - 1 ].se ];
			rest[i][need]--;
			rest[i][(need - 1 + 3) % 3]--;
			rest[i][0] += rest[ L[i] - 1 ][0];
			rest[i][1] += rest[ L[i] - 1 ][1];
			rest[i][2] += rest[ L[i] - 1 ][2];
			L[i] = L[ L[i] - 1 ];
		}
		if( pos[ block[i].se ] - pos[ block[ L[i] - 1 ].se ] >= N) { cout << "Yes\n"; return ; }
	}
	cout << "No\n"; return ;
}

signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	int T; cin >> T;
	while(T--) Solve();
	return 0;
}

M. Maimai DX 2077#

直接根据表格计算 A0,A,B0,B 即可。

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define int long long
using namespace std;

const int MAXN = 2e5 + 5;

double c[10][10], A0, A, B0, B, ach;

signed main()
{
	//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	for(int i = 1; i <= 4; i++) {
		for(int j = 0; j < 5; j++) scanf("%lf", &c[i][j]);
		//for(int j = 0; j < 5; j++) cout << c[i][j] << " "; cout << "\n";
	}
	
	A0 = 1.0 * (c[1][0] + c[1][1]) + 0.8 * c[1][2] + 0.5 * c[1][3]
	+ 2.0 * (c[2][0] + c[2][1]) + 1.6 * c[2][2] + 1.0 * c[2][3]
	+ 3.0 * (c[3][0] + c[3][1]) + 2.4 * c[3][2] + 1.5 * c[3][3]
	+ 5.0 * (c[4][0] + c[4][1]) + 2.5 * c[4][2] + 2.0 * c[4][3];
	A = 1.0 * (c[1][0] + c[1][1] + c[1][2] + c[1][3] + c[1][4])
	+ 2.0 * (c[2][0] + c[2][1] + c[2][2] + c[2][3] + c[2][4])
	+ 3.0 * (c[3][0] + c[3][1] + c[3][2] + c[3][3] + c[3][4])
	+ 5.0 * (c[4][0] + c[4][1] + c[4][2] + c[4][3] + c[4][4]);
	B0 = 1.0 * c[4][0] + 0.5 * c[4][1] + 0.4 * c[4][2] + 0.3 * c[4][3];
	B = 1.0 * c[4][0] + 1.0 * c[4][1] + 1.0 * c[4][2] + 1.0 * c[4][3] + 1.0 * c[4][4];
	//cout << A0 << " " << A << " " << B0 << " " << B << "\n";
	ach = 100.0 * A0 / A + B0 / B;
	printf("%.9lf", ach);
	return 0;
}

作者:Orzjh

出处:https://www.cnblogs.com/Orzjh/p/16612864.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Orzjh  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu