首页 > 其他分享 >Codeforces Round 926 (Div. 2) 总结

Codeforces Round 926 (Div. 2) 总结

时间:2024-02-16 22:13:52浏览次数:32  
标签:cout 标记 int Codeforces long cin Div 926 MOD

A

题意:
给出一个数组,让你重新排序,\(\sum_{i=1}^{n-1}a_i-a_{i+1}\) 最大。
做法:
显然从小到大排序即可,答案就是最大值减去最小值。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,MOD=998244353;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int T;cin>>T;
	while(T--)
	{
		int n,minn=0x3f3f3f3f,maxn=0;
		cin>>n;
		for(int i=1;i<=n;i++)
		{
			int x;cin>>x;
			minn=min(minn,x);
			maxn=max(maxn,x);
		}
		cout<<maxn-minn<<endl;
	}
}

B

题意:
给出一个的 \(n\times n\) 网格图,在所有的 \(4n-2\) 条对角线中,要求至少 \(k\) 条对角线上存在被涂黑的格子。问至少几个格子被涂黑。
做法:
使用优先涂第一行和最后一行(除第一列和最后一列)的方法可以做到每次涂都增加两个符合要求的对角线,最后两次涂色只增加 \(1\) 。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,MOD=998244353;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int T;cin>>T;
	while(T--)
	{
		int n,k;cin>>n>>k;
		int ans=(k+1)/2;
		if(k==4*n-2) ans++;
		cout<<ans<<endl;
	}
}

C

题意:
假如你在进行一个赌注游戏,给定三个整数 \(k,m,n\) ,游戏有无限多局, \(k\) 表示赢下一局能翻 \(k\) 倍, \(m\) 表示连输的局数少于 \(m\),\(n\) 表示初始的钱。问是否存在一种策略,使得在无限多局之后能够赚到无数多的钱。
做法:
电影《孤注一掷》中提到过,在一个赌局中,如果每赢一局钱翻倍,那么只要不断参加这个赌局,每次投入的前是上一次的两倍,直到赢下一局,就可以保证赚钱。(前提是可能赢)
所以这道题的策略其实就是保证自己如果赢了一局,就能把前面的亏损全部赚回来并且赚更多的钱。假设之前已经投入了 \(s\) 的钱,那么下一局就要投入 \(\lceil\frac{s+1}{k-1}\rceil\) 的钱。
计算自己的钱能否支撑到必定赢的第 \(m\) 局即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,MOD=998244353;
int n;
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int T;cin>>T;
	while(T--)
	{
		int n,x,k;cin>>k>>x>>n;
		int ans=1,sum=1;
		bool flag=1;
		while(x--)
		{
			int tmp=ceil((sum+1.0)/(k-1));
			sum+=tmp;
			if(sum>n) flag=0;
		}
		cout<<(flag?"Yes":"No")<<endl;
	}
}

D

题意:
给定一棵树,你可以给其中一些点标记(可以不标记),限制是对于每一条简单路径不存在三个被标记的点。求做标记的方案数。
做法:
dp,发现对于节点 \(x\) 的一棵以 \(y\) 为根子树中,只需要明确 \(y\) 子树中是否存在标记点,是否存在一对有祖先关系的标记点,就可以进行转移,与 \(y\) 子树内标记点的具体分布无关。
设 \(f[x][0/1/2]\) 表示以 \(x\) 为根的子树中,从 \(x\) 向下的一条链中标记点最多的链上有 \(0/1/2\) 个标记点的合法方案数。

\[f[x][0]=1 \]

\[f[x][1]=\prod f[y][1]+f[y][0] \]

\[f[x][2]=\sum f[y][2]+f[y][1] \]

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,MOD=998244353;
vector<int> to[N];
int f[N][3];
void dfs(int x,int fa)
{
	f[x][0]=1,f[x][1]=1,f[x][2]=0;
	int mul1=1,mul2=1,sum1=0,sum2=0;
	for(int y:to[x])
	{
		if(y==fa) continue;
		dfs(y,x);
		mul1=mul1*(f[y][1]+1)%MOD;
		mul2=mul2*(f[y][2]+f[y][1]+1)%MOD;
		sum1=(sum1+f[y][1])%MOD;
		sum2=(sum2+f[y][2])%MOD;
	}
	f[x][1]=mul1;
	f[x][2]=(sum1+sum2)%MOD;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int T;cin>>T;
	while(T--)
	{
		int n;cin>>n;
		for(int i=1;i<n;i++)
		{
			int u,v;cin>>u>>v;
			to[u].push_back(v);
			to[v].push_back(u);
		}
		dfs(1,0);
		cout<<(f[1][0]+f[1][1]+f[1][2])%MOD<<endl;
		
		for(int i=1;i<=n;i++) to[i].clear();
	}
}

E

题意:
给定一棵树,和 \(m(m\leq 20)\) 对点对,要求标记一些边,使得每一对点对表示的简单路径上至少有一条边被标记。问最少要标记几条边。
做法:
由于 \(m\) 很小,想到点对集合可以压成一个二进制数。所以可以直接将 \(m\) 条简单路径覆盖到树上,再把每一条树边能覆盖到的点对集合拿出来,经过去重后不同的集合的数量和 \(m\) 同级,最后直接用 \(O(2^m m)\) 的状压dp求出即可。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+5,MOD=998244353;
int n;
vector<int> to[N];
int tag[N],f[1<<21],po[N],tot;
void dfs(int x,int pre)
{
	for(int y:to[x])
	{
		if(y==pre) continue;
		dfs(y,x);
		tag[x]^=tag[y];
	}
	po[++tot]=tag[x];
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	int T;cin>>T;
	while(T--)
	{
		cin>>n;
		for(int i=1;i<n;i++)
		{
			int u,v;
			cin>>u>>v;
			to[u].push_back(v);
			to[v].push_back(u);
		}
		int m;cin>>m;
		for(int i=1;i<=m;i++)
		{
			int u,v;
			cin>>u>>v;
			tag[u]^=(1<<i-1);
			tag[v]^=(1<<i-1);
		}
		dfs(1,0);
		sort(po+1,po+tot+1);
		tot=unique(po+1,po+tot+1)-po-1;
		for(int i=1;i<(1<<m);i++) f[i]=0x3f3f3f3f;
		f[0]=0;
		for(int i=0;i<(1<<m);i++)
			for(int j=1;j<=tot;j++)
				f[i|po[j]]=min(f[i|po[j]],f[i]+1);
		cout<<f[(1<<m)-1]<<endl;
		
		for(int i=1;i<=n;i++) to[i].clear(),tag[i]=0;
		tot=0;
	}
}

标签:cout,标记,int,Codeforces,long,cin,Div,926,MOD
From: https://www.cnblogs.com/napnah/p/18017555

相关文章

  • Codeforces Round 926 (Div. 2) DEF
    D.SashaandaWalkintheCity题意:给定一棵树,问不存在三个点属于同一条路径的点集个数。\(f[x]\)表示,最近公共祖先为\(x\)的合法非空集数量。如果选\(x\),那么只能为不选子树或选一棵子树,否则\(u\insubtree[y_1]\),\(v\insubtree[y_2]\)与\(x\)共链。?贡献为\(......
  • Codeforces Round 926 (Div. 2) 赛后总结
    这场比赛掉了前三场比赛上的分,望周知。SashaandtheBeautifulArray题目大意:一个有n个数的数组,对n个数进行排序,求数组中ai-ai-1(下标从2到n)的和的最大值。分析列出来和式,为an-an-1+an-1-an-2……-a1最后得到an-a1那么an最大,a1最小即可。很容易想到排序。#include<i......
  • Codeforces Round 926 (Div. 2)(A~D)
    目录ABCDA输出最大值减最小值,或者排序算一下答案#include<bits/stdc++.h>#defineintlonglong#definerep(i,a,b)for(inti=(a);i<=(b);++i)#definefep(i,a,b)for(inti=(a);i>=(b);--i)#definepiipair<int,int>#definelllonglong#definedb......
  • Codeforces Round 926 (Div. 2) 题解
    比赛链接:https://codeforces.com/contest/1929官解链接:https://codeforces.com/blog/entry/125943出的很差的一场。推歌CF1929A.SashaandtheBeautifulArray题意任意排列数组\(a_{1..n}\),求\(\sum_{i=2}^n(a_i-a_{i-1})\)的最大值。题解见过最显然的A题,奠定了......
  • Codeforces Round 926 (Div. 2)
    A-SashaandtheBeautifulArray给出的是差分的和,显然等于最后一个减掉第一个,于是答案为最大值减最小值。SubmissionB-SashaandtheDrawing观察到:前几次操作可以使答案\(+2\),之后每次只能让答案\(+1\)。手玩一下发现最优方案是先填满第一列,再从最后一列第二行填到倒......
  • CF-926(已更新:B)
    CF-926两点睡,七点起,阎王夸我好身体……主要这场实在是难绷,两个小时都在C题上吊死了,也不是没想过跳题,只是后面的题我更是一点思路都没有-^-“就喜欢这种被揭穿的感觉,爽!”B分析​ 涂色的单元格能够包含k种对角线,很明显要根据图像的具体性质想答案:然而我赛时是一股脑地猜结......
  • Codeforces Round 906 (Div. 2)
    A.Doremy'sPaint3对于式子\(b_1+b_2=b_2+b_3=\dots=b_{n-1}+b_n=k\),从中挑出\(b_i+b_{i+1}=b_{i+1}+b_{i+2}\),得到\(b_i=b_{i+2}\),这就意味着所有奇数位置上的数需要相等,所有偶数位置上的数也需要相等。对于\(n\)个数而言,有\(\lceil\frac{n}{2}\rc......
  • 数组元素关系映射——cf_925_D. Divisible Pairs
    目录问题概述思路分析参考代码做题反思问题概述原题参考:D.DivisiblePairs给出整数n、x、y和长度为n的数组,要求求出数组中满足以下关系的数对x|ai+ajy|ai-aji<j思路分析刚开始看到这个题的时候觉得没思路,坐牢卡半天发现感觉是对的(裂开)。题解给的是map的做法,看完之......
  • Codeforces 做题笔记
    1841EFilltheMatrix刚开始思路错了,以为就从下往上铺但发现要尽量让横的连续段断开的次数少,每断开一次相当于数量\(-1\)所以从宽度最大的矩形开始填,尽量填满可以用set维护当前行的连续段,这一列遇到黑格就split,去除宽度为\(1\)的,同时记录加入的时间戳来计算矩形高度vo......
  • Codeforces Round 925 (Div. 3)
    A简单分讨。最前面a能放多少就放多少,大头尽量放在后面。B先算出每个水缸最终的水量,然后从前往后扫,多的水平到下一个水缸里去。假如扫到一个水缸小于平均值,那么没救了,输出NO。CC<<B。考虑全体值为\(a_1\)与\(a_n\)时的最小代价,搞两个指针,从前后开始扫一扫即可。D......