Codeforces Round 958 (Div 2)(A—D题解)

Codeforces Round 958 (Div. 2)

2024-07-17 —yimg

A

签到题

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void work()
{
	int n, k;
	cin >> n >> k;
	cout << (n - 1 + k - 2) / (k - 1) << '\n';
} 
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while(t--)
		work();
}

B

签到题

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void work()
{
	int n; string s;
	cin >> n >> s;
	int c1 = 0, c0 = 0;
	for(int i = 0; i < n; ++i){
		if(s[i] == '1') c1++;
		else if(s[i] == '0' && (i && s[i - 1] != '0' || !i) ) c0++;
	}
	cout << (c1 > c0 ? "YES" : "NO") << '\n';
} 
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while(t--)
		work();
}

C

题意:

给定正整数n, 求最长序列a,a需要满足

  • ain1ik.

  • ai>ai12ik.

  • ai|ai1=n2ik

思路:

首先根据相邻两位按位or为n,我们可以忽略对构造答案没有影响的0位, 接下来对2num(1)1 进行操作,ak一定为2num(1)1 , 贪心的想 : ak1 为小于ak 的符合要求的最大值 , 即2num(1)120 ,我们可以据此构造出num(1) + 1个答案。

实现上,依次删去最高位就能得到答案。

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void work()
{
	ll n;
	cin >> n;
	vector<int> p;
	ll a = 0, pre = 0;
	for(ll i = 0, tmp = n; tmp; tmp >>= 1, ++i){
		if(tmp&1){
			a++;
			p.push_back(i);
		}
	}
	if(a == 1) cout << 1 << "\n";
	else cout << a + 1 << '\n';
	for(ll i = a - 1; a > 1 && i >= 0; --i){
		ll res = n - (1ll << p[i]);
		cout << res << " ";
	}
	cout << n;
	cout << '\n';
} 
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while(t--)
		work();

D

题意:

有一颗n个节点的数,每个节点上都有一个攻击力为ai怪物,怪物每回合开始时结算一次攻击,每个回合中可以进行操作,消灭任意只指定怪物,但是不能消灭相邻两个节点的怪物,问受到的攻击值之和最小为多少。

思路:

选择在第k回合消灭攻击力为ai 的怪物需要受到攻击kai , 冲突的情况只有相邻节点有影响,考虑用动态规划解决。对于整个问题,回合数最多为log(n) (这个上限不知道怎么证明)。

fu,i 为以u为根节点的子树,选择回合i时的最小值。记录子节点的最小值和次小值,进行状态转移即可。复杂度为O(nlogn)

代码:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
void work()
{
	int n;
	cin >> n;
	vector<ll> a(n + 1);
	vector<vector<ll>> g(n + 1);
	for(int i = 1; i <= n; ++i)
		cin >> a[i];
	for(int i = 1; i < n; ++i){
		int u, v;
		cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	int lgn = __lg(n) + 1;
	vector<vector<ll>> f(n + 1, vector<ll>(lgn + 1));
	auto dfs = [&](auto &&self, int u, int p) -> void{
		for(int i = 1; i <= lgn; ++i)
			f[u][i] = a[u] * i;
		for(auto v : g[u]){
			if(v == p) continue;
			self(self, v, u);
			ll minn = 1e18, lm = 1e18, id = 0;
			for(int i = 1; i <= lgn; ++i){
				if(f[v][i] < lm){
					lm = f[v][i];
					if(lm < minn){
						id = i;
						swap(lm, minn);
					}
				}
			}
			for(int i = 1; i <= lgn; ++i){
				if(i == id) f[u][i] += lm;
				else f[u][i] += minn; 
			}
		}
	};
	dfs(dfs, 1, -1);
	ll minn = 1e18;
	for(int i = 1; i <= lgn; ++i) minn = min(minn, f[1][i]);
	cout << minn << "\n";
} 
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int t;
	cin >> t;
	while(t--)
		work();
}
posted @   _yimg  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示