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\),考虑怎么去判断可行性。
考虑分讨:
- \(j<i\)
此时需要满足 \(x-n+j \geq a_j\)。
- \(j>i\)
此时需要满足 \(x-j+1 \geq a_j\)。
- \(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;
}