Educational Codeforces Round 158

打烂了,D 吃了 \(5\) 发罚时。

最后 \(5 \ \mathrm{min}\) 过 E。

A

最后一次往返要算 \(a_n\)\(x\) 距离两倍,其余情况皆是 \(a_i-a_{i-1}\),模拟求最大值即可。

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#pragma GCC optimize("Ofast","unroll-loops","inline")
#include<bits/stdc++.h>
#define ll long long
//#define int ll
using namespace std;
const int N=2e5+60,M=2e6+20,mod=998244353;
int n,a[N],m;
void solve(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	int mx=0;
	for(int i=1;i<=n;i++) mx=max(mx,a[i]-a[i-1]);
	mx=max(mx,2*(m-a[n]));
	cout<<mx<<'\n';
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

B

不妨应定每次连续给一个区间加一后必须跳到某个开头,即花费为 \(1\),考虑到最有决策中一定存在开头为 \(1\) 的,所以不用考虑开局处在 \(1\) 就跳的情况。

题意转化为选择一段区间加一花费为 \(1\),最小化花费,典,从左往右贪心即可,考虑最后选的区间不用跳,减一即是答案。

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#pragma GCC optimize("Ofast","unroll-loops","inline")
#include<bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int N=2e5+60,M=2e6+20,mod=998244353;
int n,a[N],x;
void solve(){
	cin>>n;x=0;
	for(int i=1;i<=n;i++) cin>>a[i];
	int ans=a[1];x=a[1];
	for(int i=2;i<=n;i++){
		if(x<a[i]) ans+=a[i]-x,x=a[i];
		else x=min(x,a[i]); 
	}
	cout<<ans-1<<'\n';
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

C

不难发现最大值最小值一定不会变到其他位置,考虑相等时相当于是最大值最小值两个位置对应数相等。

不难发现,\(x=0/1\)

贪心,决策为当前最低为是最小值 \(1\),最大值 \(0\) 选择加 \(1\)\(2\),其余情况均选择直接除以 \(2\)

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#pragma GCC optimize("Ofast","unroll-loops","inline")
#include<bits/stdc++.h>
#define ll long long
//#define int ll
#define pb push_back
using namespace std;
const int N=2e5+60,M=2e6+20,mod=998244353,LGN=30;
int n,a[N],b[N],mx,mn;
vector<int> ans;
void solve(){
	cin>>n;mx=-1e9,mn=1e9;
	ans.clear();
	for(int i=1;i<=n;i++) cin>>a[i],mx=max(mx,a[i]),mn=min(mn,a[i]);
	if(n==1) return cout<<0<<'\n',void();
	int t=0;
	for(t=0;t<=LGN;t++){
		if(mx==mn) break;
		if(!(mx&1)){
			mx++,mn++;
			mx>>=1;mn>>=1;
			ans.pb(1);
		}
		else{
			mx>>=1;mn>>=1;
			ans.pb(0);
		}
	}
	cout<<t<<'\n';
	if(t<=n){
		for(int v:ans) cout<<v<<' ';cout<<'\n';
	}
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}

D

二分答案 \(x\),考虑怎么去判断可行性。

考虑分讨:

  1. \(j<i\)

此时需要满足 \(x-n+j \geq a_j\)

  1. \(j>i\)

此时需要满足 \(x-j+1 \geq a_j\)

  1. \(j=i\)

此时需要满足 \(x \geq a_i\)

不难发现一个位置可以被选为 \(i\) 当且仅当,前面所有位置满足 \(1\),后面所有位置满足 \(2\),自己满足 \(3\)

直接模拟即可,复杂度 \(O(n \log V)\)

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#pragma GCC optimize("Ofast","unroll-loops","inline")
#include<bits/stdc++.h>
#define ll long long
#define int ll
using namespace std;
const int N=3e5+60,M=2e6+20,Inf=2e9;
int n,a[N],c1[N],c2[N];
bool chk(int x){
	c1[0]=c2[n+1]=1;
	for(int i=1;i<=n;i++) c1[i]=x-n+i>=a[i];
	for(int i=1;i<=n;i++) c2[i]=x-i+1>=a[i];
	for(int i=1;i<=n;i++) c1[i]&=c1[i-1];
	for(int i=n;i;i--) c2[i]&=c2[i+1];
	for(int i=1;i<=n;i++){
		if(c1[i-1]&&c2[i+1]&&x>=a[i]) return 1;
	}
	return 0;
}
signed main(){
//	freopen("a.in","r",stdin);
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int l=0,r=1e12,ans=1e12;
	while(l<=r){
		int mid=(l+r)>>1;
		if(chk(mid)) r=mid-1,ans=mid;
		else l=mid+1;
	}
	cout<<ans<<'\n';
	return 0;
}

E

好像是 sb 题?

\(f_{u,0/1/2/3}\) 表示,只考虑 \(u\) 子树内的答案,强制应定选择 \(u\) 节点,考虑与 \(u\) 相连的点的个数为 \(0/1/2/\geq 3\)

直接大力转移即可,答案就是 \(\max_{u} \{f_{u,0},f_{u,1},f_{u,2}-a_u,f_{u,3}\}\)

复杂度 \(O(n)\)

#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2")
#pragma GCC optimize("Ofast","unroll-loops","inline")
#include<bits/stdc++.h>
#define ll long long
#define int ll
#define pb push_back
using namespace std;
const int N=5e5+60,M=2e6+20,mod=998244353,Inf=1e16;
vector<int> e[N];
int n,a[N],f[N][4],g[N],ans;
void dfs(int u,int fa){
	f[u][0]=a[u];
	for(int v:e[u]) if(v!=fa){
		dfs(v,u);
		f[u][3]=max(f[u][3],f[u][3]+g[v]);
		f[u][3]=max(f[u][3],f[u][2]+g[v]);
		f[u][2]=max(f[u][2],f[u][1]+g[v]);
		f[u][1]=max(f[u][1],f[u][0]+g[v]);
	}
	g[u]=max(f[u][0],f[u][1]-a[u]);
	g[u]=max(g[u],f[u][2]);
	g[u]=max(g[u],f[u][3]);
	int res=max(0ll,f[u][0]);
	res=max(res,f[u][1]);res=max(res,f[u][2]-a[u]);
	res=max(res,f[u][3]);
	ans=max(ans,res);
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) for(int j=0;j<4;j++) f[i][j]=-Inf;
	for(int i=1;i<=n;i++) g[i]=-Inf;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) e[i].clear();
	for(int i=1,u,v;i<n;i++){
		cin>>u>>v;e[u].pb(v);e[v].pb(u);
	}
	ans=-Inf;
	dfs(1,0);
	cout<<ans<<'\n';
}
signed main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;
	while(T--) solve();
	return 0;
}
posted @ 2023-11-25 00:34  Detect-Perplexity  阅读(15)  评论(0编辑  收藏  举报