AtCoder Beginner Contest 366 补题记录(A~G)

又寄咯

A

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<memory.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
int a[N];
signed main(){
    int n,t,a;
    cin>>n>>t>>a;
    if(t==a)cout<<"No\n";
    else{
        if(t>a)swap(t,a);
        t+=(n-t-a);
        if(t>a)cout<<"No\n";
        else cout<<"Yes\n";
    }
    return 0;
} // main

B

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<memory.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
string s[N];
char res[2010][2010];
signed main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;++i)cin>>s[i];
    reverse(s+1,s+n+1);
    int mx=0;for(int i=1;i<=n;++i)mx=max(mx,(int)s[i].size());
    for(int i=1;i<=mx+1;++i){
        int id=0;
        for(int j=1;j<=n;++j)
            if(s[j].size()>=i)res[i][j]=s[j][i-1],id=j;
        for(int j=1;j<=id;++j)
            if(!res[i][j])res[i][j]='*';
        for(int j=1;j<=n;++j)
            if(res[i][j])cout<<res[i][j];cout<<'\n';
    }
    return 0;
} // main

C

开一个桶维护当前在集合内的所有元素及它们的出现次数即可。时间复杂度为 \(O(n)\)

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<memory.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
int a[N],box[N],cnt;
signed main(){
    int q;cin>>q;
    while(q--){
        int o,x;
        cin>>o;
        if(o==1){
            cin>>x;
            ++box[x];
            if(box[x]==1)++cnt;
        }else if(o==2){
            cin>>x;
            --box[x];
            if(!box[x])--cnt;
        }else{
            cout<<cnt<<'\n';
        }
    }
    return 0;
} // main

D

三维前缀和板子。时间复杂度为 \(O(n^3+Q)\)

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<memory.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
int a[110][110][110];
int s[110][110][110];
signed main(){
    int n;cin>>n;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    for(int k=1;k<=n;++k)cin>>a[i][j][k];
    for(int i=1;i<=n;++i)
    for(int j=1;j<=n;++j)
    for(int k=1;k<=n;++k){
        s[i][j][k]=s[i-1][j][k]+s[i][j-1][k]+s[i][j][k-1]-s[i][j-1][k-1]-s[i-1][j][k-1]-s[i-1][j-1][k]+a[i][j][k]+s[i-1][j-1][k-1];
    }
    int q;cin>>q;while(q--){
        int l1,r1,l2,r2,l3,r3;cin>>l1>>r1>>l2>>r2>>l3>>r3;
        cout<<s[r1][r2][r3]-s[l1-1][r2][r3]-s[r1][l2-1][r3]-s[r1][r2][l3-1]+
        s[l1-1][l2-1][r3]+s[l1-1][r2][l3-1]+s[r1][l2-1][l3-1]-s[l1-1][l2-1][l3-1]<<'\n';
    }
    return 0;
} // main

E

首先三分出解数量最多的行,然后向左右二分扩展出最远有多少行中存在至少一个解。对于每一个可能有解的行先三分出哪个位置可能有解,然后往上下二分扩展出最远到哪里有解即可。容易证明时间复杂度正确。

#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<memory.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
int x[N],y[N],n,d,MID;
int get(int X){
    int sum=0;
    for(int i=1;i<=n;++i)
        sum+=abs(MID-y[i])+abs(X-x[i]);
    return sum;
}
bool check(int X){
    int cnt=0;
    for(int i=1;i<=n;++i)
        cnt+=abs(MID-y[i])+abs(X-x[i]);
    return cnt<=d;
}
int get2(int hang,int X){
    int val=0;
    for(int i=1;i<=n;++i)
        val+=abs(hang-x[i])+abs(X-y[i]);
    return val;
}
bool check2(int hang,int X){
    return get2(hang,X)<=d;
}
signed main(){
    cin>>n>>d;
    for(int i=1;i<=n;++i)cin>>x[i]>>y[i];
    vector<int>v;
    for(int i=1;i<=n;++i)v.pb(y[i]);
    sort(v.begin(),v.end());
    MID=v[v.size()/2];
    int cnt=0;
    int l=-2000000,r=2000000,best=-1;
    while(l<=r){
        int m1=l+(r-l)/3,m2=r-(r-l)/3;
        if(get(m1)>get(m2))
            best=m2,l=m1+1;
        else
            best=m1,r=m2-1;
    }
    int pos=best;
    // cout<<"pos="<<pos<<'\n';
    l=-2000000,r=pos;
    best=-998244353;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))
            best=mid,r=mid-1;
        else
            l=mid+1;
    }
    if(best==-998244353){
        cout<<"0\n";
        return 0;
    }
    int zuo=best;
    l=pos,r=2000000;
    while(l<=r){
        int mid=l+r>>1;
        if(check(mid))
            best=mid,l=mid+1;
        else
            r=mid-1;
    }
    int you=best;
    for(int i=zuo;i<=you;++i){
        int l=-2000000,r=2000000,best=-1;
        while(l<=r){
            int m1=l+(r-l)/3,m2=r-(r-l)/3;
            if(get2(i,m1)>get2(i,m2))
                best=m2,l=m1+1;
            else
                best=m1,r=m2-1;
        }
        int pos=best;
        l=-2000000,r=pos;
        best=-998244353;
        while(l<=r){
            int mid=l+r>>1;
            if(check2(i,mid))
                best=mid,r=mid-1;
            else
                l=mid+1;
        }
        if(best==-998244353)
            continue;
        int qw=best;
        l=pos,r=2000000;
        while(l<=r){
            int mid=l+r>>1;
            if(check2(i,mid))
                best=mid,l=mid+1;
            else
                r=mid-1;
        }
        cnt+=best-qw+1;
    }
    cout<<cnt<<'\n';
    return 0;
} // main

F

可以先贪心再随机化选取,能过,也可以按照 \(B_iA_j+B_j>A_iB_j+A_j\) 的策略排序然后设 \(f_{i,j}\) 表示前 \(i\) 个数选了 \(j\) 个的最大值,此时转移显然。均可以通过。

方法 \(1\) 代码:

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=1000100;
struct qwq{
    int a,b;
    bool operator<(const qwq&r){
        return a>r.a||a==r.a&&b>r.b;
    }
    bool operator>(const qwq&r){
        return b>r.b||b==r.b&&a>r.a;
    }
}z[N];
bool cmp(qwq a,qwq b){
    return a.a>b.a||a.a==b.a&&a.b<b.b;
}
int vis[N];
signed main(){
    int n,k;cin>>n>>k;
    int cost=0;
    for(int i=1;i<=n;++i)cin>>z[i].a>>z[i].b;
    sort(z+1,z+n+1);
    int mx=0,now=1;
    for(int i=1;i<=k;++i)
        now=now*z[i].a+z[i].b;
    mx=now;
    now=1;
    for(int i=k;i;--i)
        now=now*z[i].a+z[i].b;
    mx=max(mx,now);
    sort(z+1,z+n+1,greater<>());
    now=1;
    for(int i=1;i<=k;++i)
        now=now*z[i].a+z[i].b;
    mx=max(mx,now);
    now=1;
    for(int i=k;i;--i)
        now=now*z[i].a+z[i].b;
    mx=max(mx,now);
    sort(z+1,z+n+1,cmp);
    now=1;
    for(int i=1;i<=k;++i)
        now=now*z[i].a+z[i].b;
    mx=max(mx,now);
    now=1;
    for(int i=k;i;--i)
        now=now*z[i].a+z[i].b;
    mx=max(mx,now);
    now=1;
    sort(z+1,z+n+1,greater<>());
    for(int i=1;i<=k;++i){
        int tmp=-1;
        for(int j=1;j<=n;++j)
            if(!vis[j]){
                if(tmp==-1)tmp=j;
                else{
                    int yy=now*z[tmp].a+z[tmp].b;
                    int xx=now*z[j].a+z[j].b;
                    if(xx>yy)tmp=j;
                }
            }
        now=now*z[tmp].a+z[tmp].b;
        vis[tmp]=1;
    }
    mx=max(mx,now);
    do{
        now=1;
        random_shuffle(z+1,z+n+1);
        for(int i=1;i<=k;++i)
            now=now*z[i].a+z[i].b;
        mx=max(mx,now);
    }while(1.*clock()/CLOCKS_PER_SEC<1.97);
    cout<<mx<<'\n';
    return 0;
} // main

G

问题可以转化为对于每一个满足 \(\deg(i)>1\)\(i\),都需要满足 \(x_{v_1}\oplus x_{v_2}\oplus x_{v_3}\oplus\ldots\oplus x_{v_k}=0\),其中 \(v_1,v_2,v_3,\ldots,v_k\)\(i\) 点所有的出边可以走到的点。发现 \(n\) 十分小所以直接暴力高斯消元解异或方程组即可。

时间复杂度为 \(O(n^3)\),可以通过。

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define int long long
#define pb push_back
using namespace std;
const int N=500100;
int mp[110][110],F[N];
signed main(){
    int n,m;cin>>n>>m;
    while(m--){
        int a,b;cin>>a>>b;
        mp[a][b]=mp[b][a]=1;
    }
    for(int i=1;i<=n;++i){
        int id=i;
        for(int j=i+1;j<=n;++j)
            if(mp[j][i]>mp[id][i])id=j;
        for(int j=1;j<=n+1;++j)
            swap(mp[i][j],mp[id][j]);
        if(mp[i][i]){
            for(int j=i+1;j<=n;++j){
                int x=mp[j][i];
                for(int k=i;k<=n+1;++k)
                    mp[j][k]^=(mp[i][k]*x);
            }
        }
    }
    F[n]=mp[n][n+1];
    int zhi=0;
    if(mp[n][n]==0){
        if(F[n]){
            cout<<"No\n";
            return 0;
        }
        F[n]=1e18;
        ++zhi;
    }
    for(int i=n-1;i;--i){
        for(int j=i+1;j<=n;++j)
            mp[i][n+1]^=(mp[i][j]*F[j]);
        F[i]=mp[i][n+1];
        if(!mp[i][i]){
            if(F[i]){
                cout<<"No\n";
                return 0;
            }else
                F[i]=(int)(1e18)+(zhi++);
        }
    }
    vector<int>res;
    // cout<<"qwq: ";for(int i=1;i<=n;++i)cout<<F[i]<<' ';cout<<'\n';
    for(int i=1;i<=n;++i)
        if(!F[i]){
            cout<<"No\n";
            return 0;
        }else
            res.pb(F[i]);
    cout<<"Yes\n";
    for(auto &x:res)
        cout<<x<<' ';
    cout<<'\n';
    return 0;
} // main
posted @ 2024-08-10 22:09  yhbqwq  阅读(75)  评论(0编辑  收藏  举报