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
posted @ 2024-08-11 09:15  yhbqwq  阅读(90)  评论(0编辑  收藏  举报