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

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

A

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

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define endl '
'
#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 '
'
#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 '
'
#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 '
'
#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;
}
原文地址:https://www.cnblogs.com/Tenshi/p/14810240.html