Codeforces Round #722 (Div. 2) 部分题解

Posted HinanawiTenshi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #722 (Div. 2) 部分题解相关的知识,希望对你有一定的参考价值。

这次的题目挺简单的(指签到题

A

最小的数肯定去不掉,而不是最小的数一定可以在一定的操作后去掉,所以答案为 \\(n-最小数个数\\)

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl \'\\n\'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<\'0\'||ch>\'9\') {if(ch==\'-\')x=-1;ch=getchar();}
    while(ch>=\'0\'&&ch<=\'9\') s=(s<<3)+(s<<1)+ch-\'0\',ch=getchar();
    x*=s;
}

int buc[1005];
int main(){
	int T; cin>>T;
	while(T--){
		set0(buc);
		int n;
		cin>>n;
		rep(i,1,n){
			int x;
			cin>>x;
			buc[x]++;
		}
		
		int res;
		rep(i,1,100){
			if(buc[i]){
				res=n-buc[i];
				break;
			}
		}
		
		cout<<res<<endl;
	}
    return 0;
}

B

策略:负数和 \\(0\\) 肯定要选,如果说存在正数,那么看看最小的正数是否满足,如果满足就让答案 \\(+1\\)

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl \'\\n\'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<\'0\'||ch>\'9\') {if(ch==\'-\')x=-1;ch=getchar();}
    while(ch>=\'0\'&&ch<=\'9\') s=(s<<3)+(s<<1)+ch-\'0\',ch=getchar();
    x*=s;
}

const int N=1e5+5;
int a[N];

int main(){
	int T; cin>>T;
	while(T--){
		int n; cin>>n;
		rep(i,1,n) cin>>a[i];
		sort(a+1, a+1+n);
		int minv=INF;
		
		int res=1;

		rep(i,2,n){
			minv=min(minv, a[i]-a[i-1]);
			if(a[i]<=0) {
                res++;
                continue;
            }
			if(minv>=a[i]){
				res++;
				break;
			}
		}
		cout<<res<<endl;
	}
    return 0;
}

C

简单的树形dp
一个重要结论:每个点取最小或最大值即可得到最优解。
f[u][0] 表示 \\(u\\) 点取最小值时候,\\(u\\) 点及其子树最大的贡献。
f[u][1] 表示 \\(u\\) 点取最大值时候,\\(u\\) 点及其子树最大的贡献。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl \'\\n\'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

#define int long long
inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<\'0\'||ch>\'9\') {if(ch==\'-\')x=-1;ch=getchar();}
    while(ch>=\'0\'&&ch<=\'9\') s=(s<<3)+(s<<1)+ch-\'0\',ch=getchar();
    x*=s;
}

const int N=1e5+5;

struct node{
	int to, next;
}e[N<<1];

int h[N], tot;

void add(int u, int v){
	e[tot].to=v, e[tot].next=h[u], h[u]=tot++;
}
// int minv[N], maxv[N];
int l[N], r[N];
int f[N][2];

int n, m;
void dfs(int u, int fa){
	int resl=0, resr=0;
	for(int i=h[u]; ~i; i=e[i].next){
		int go=e[i].to;
		if(go==fa) continue;
		
		dfs(go, u);
		resl+=max(f[go][0]+abs(l[u]-l[go]), f[go][1]+abs(l[u]-r[go]));
		resr+=max(f[go][0]+abs(r[u]-l[go]), f[go][1]+abs(r[u]-r[go]));
	}
	f[u][0]=resl;
	f[u][1]=resr;
}

signed main(){
	int T; cin>>T;
	while(T--){
		tot=0, memset(h, -1, sizeof h);
		read(n);
		rep(i,1,n) read(l[i]), read(r[i]);
		
		m=n-1;
		while(m--){
			int u, v; read(u), read(v);
			add(u, v), add(v, u);
		}
		
		dfs(1, -1);
		
		cout<<max(f[1][0], f[1][1])<<endl;
	}
    return 0;
}

D

将问题分成两个部分:

  1. 出现覆盖的情况
  2. 未出现覆盖的情况(也就是各个颜色占据的距离都是相等的)

考虑 \\(f[i]\\) 的状态转移方程。
对第一个部分:很容易想到这一部分的贡献:\\(\\sum_{j=1}^{i-1}f[j]\\)
而对于第二个部分,因为都是等距的,所以这部分的贡献为 \\(d[i]\\) ,其中 \\(d[i]\\)\\(i\\) 的公约数数量。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl \'\\n\'
#define debug(x) cerr << #x << ": " << x << endl
#define pb(a) push_back(a)
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<double,double> PDD;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<\'0\'||ch>\'9\') {if(ch==\'-\')x=-1;ch=getchar();}
    while(ch>=\'0\'&&ch<=\'9\') s=(s<<3)+(s<<1)+ch-\'0\',ch=getchar();
    x*=s;
}

const int N=2e6+6, mod=998244353;
ll f[N], s[N], d[N];

void get(int n)
{
	
	for(int i=1; i*i<=n; i++) 
		for(int j=i;j<n/i;j++){
			if(i==j) d[i*j]++;
			else d[i*j]+=2;
		}
}

int main(){
	int n; cin>>n;

	f[1]=1;
	s[1]=1;
	get(2*n); // 预处理出公约数 i 个数 d[i]
	rep(i, 2, n) f[i]=(d[i]+s[i-1])%mod, s[i]=(s[i-1]+f[i])%mod;
	cout<<f[n]<<endl;
	
    return 0;
}

以上是关于Codeforces Round #722 (Div. 2) 部分题解的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #722 (Div. 2) 20210525

Codeforces Round #722 (Div. 2)Codeforces-1529 ABC

Codeforces Round #722 (Div. 2)Codeforces-1529 ABCD

Codeforces Round #722 (Div. 2)Codeforces-1529 ABCD

Codeforces Round #722 (Div. 2) 部分题解

Codeforces Round #722 (Div. 2) A~D 题解