Codeforces Round 965 (Div. 2) 补题记录(A,B,D,E1)
speedforces again~
A < E1 << B < D << C
A
若 \(k\equiv 1(\bmod2)\),则构造 \((x,y)\),\((x-1,y)\),\((x+1,y)\),\((x-2,y)\),\((x+2,y)\),\(\ldots\)。
否则构造 \((x-1,y)\),\((x+1,y)\),\((x-2,y)\),\((x+2,y)\),\(\ldots\)。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
int a[N];
signed main(){
int T;cin>>T;
while(T--){
int xc,yc,k;
cin>>xc>>yc>>k;
if(k&1){
--k;
cout<<xc<<' '<<yc<<'\n';
}
int x1=xc,y1=yc,x2=xc,y2=yc;
for(int i=0;i<k;++i,++i){
--x1,++x2;
cout<<x1<<' '<<y1<<'\n';
cout<<x2<<' '<<y2<<'\n';
}
}
return 0;
} // main
B
打表可以得到将原序列位移若干位之后仍然符合条件。因此时间复杂度为 \(O(n)\)。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
int a[N];
signed main(){
int T;cin>>T;
while(T--){
int xc,yc,k;
cin>>xc>>yc>>k;
if(k&1){
--k;
cout<<xc<<' '<<yc<<'\n';
}
int x1=xc,y1=yc,x2=xc,y2=yc;
for(int i=0;i<k;++i,++i){
--x1,++x2;
cout<<x1<<' '<<y1<<'\n';
cout<<x2<<' '<<y2<<'\n';
}
}
return 0;
} // main
D
容易发现当且仅当 Elsie 位于 Bessie 从来没有到过的结点,且通过位于该点的一个次要桥梁可以到达的结点超过了 Bessie。
因此可以建图跑最短路,找到 Elsie 能够到达每一个点所需要的最少时间。于是可以枚举每一条备选边 \(u\to v\),若满足 \(u<s\) 且 Elsie 到达 \(v\) 的时候 Bessie 没有到达 \(v\) 那么就可以获胜。因此只需要维护不等式 \(v-d_v+1\ge s\) 且还需要满足 \(u<s\) 即可知道满足 Elsie 能够获胜的所有点。满足条件的区间即为 \([u+1,v-d_v-1]\),用差分维护一下即可。时间复杂度为 \(O(n)\)(图为 DAG,可以直接 dp 求解最短路)。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=500100;
vector<int>z[N];int f[N],cf[N];
signed main(){
int T;cin>>T;
while(T--){
int n,m;cin>>n>>m;
for(int i=1;i<=n;++i)z[i].clear(),cf[i]=0;
for(int i=1;i<n;++i)z[i].pb(i+1);
while(m--){
int a,b;cin>>a>>b;
z[a].pb(b);
}
for(int i=1;i<=n;++i)f[i]=1e18;
f[1]=0;
for(int i=1;i<=n;++i)
for(auto&j:z[i]){
f[j]=min(f[j],f[i]+1);
if(i+1<=j-f[j]-1)++cf[i+1],--cf[j-f[j]];
}
for(int i=1;i<=n;++i)cf[i]+=cf[i-1];
for(int i=1;i<n;++i)
if(cf[i])cout<<"0";
else cout<<"1";
cout<<'\n';
}
return 0;
} // main
E1
确定不是这个?
枚举每一个位置,然后暴力二分向左、右扩展。因为每扩展一次就会翻倍所以最多只会二分扩展 \(O(\log n)\) 次,因此总的时间复杂度为 \(O(n\log^2n)\)。
#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=200100;
int a[N],s[N];
signed main(){
// freopen("1.out","w",stdout);
int T;cin>>T;
while(T--){
int n,m;cin>>n>>m;
for(int i=1;i<=n;++i)cin>>a[i],s[i]=s[i-1]+a[i];
if(n==1){
cout<<"1\n";
continue;
}
int cnt=0;
for(int i=1;i<=n;++i){
int p=a[i];
if(i!=1&&a[i]>=a[i-1]||i!=n&&a[i]>=a[i+1]){
int L=i,R=i,now=a[i];
while(L!=1||R!=n){
if(L!=1&&now>=a[L-1]){
int l=1,r=L-1,best=-1;
while(l<=r){
int mid=l+r>>1;
// [mid,L-1] ; now
if(now>=s[L-1]-s[mid-1])
best=mid,r=mid-1;
else
l=mid+1;
}
// cout<<"cf "<<L<<' '<<R<<' '<<best<<'\n';
assert(~best);
L=best;
}else if(R!=n&&now>=a[R+1]){
int l=R+1,r=n,best=-1;
while(l<=r){
int mid=l+r>>1;
// [R+1,mid] ; now
if(now>=s[mid]-s[R])
best=mid,l=mid+1;
else
r=mid-1;
}
// cout<<"mm "<<L<<' '<<R<<' '<<best<<'\n';
assert(~best);
R=best;
}else break;
now=s[R]-s[L-1];
}
if(L==1&&R==n)++cnt;
}
}
cout<<cnt<<'\n';
}
return 0;
} // main
本文来自博客园,作者:yhbqwq,转载请注明原文链接:https://www.cnblogs.com/yhbqwq/p/18353091,谢谢QwQ