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