AtCoder Beginner Contest 380

这次写了五道题,有点进步。

A - 123233

难度:红


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mxn 100010
int n,m,cnt[10];
char a;
void solve(){
    cin>>a;cnt[a-'0']++;
    cin>>a;cnt[a-'0']++;
    cin>>a;cnt[a-'0']++;
    cin>>a;cnt[a-'0']++;
    cin>>a;cnt[a-'0']++;
    cin>>a;cnt[a-'0']++;
    if(cnt[1]==1&&cnt[2]==2&&cnt[3]==3)cout<<"Yes";
    else cout<<"No";
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int T=1;while(T--)solve();
    return 0;
}

B - Hurdle Parsing

难度:红


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mxn 100010
int n,m,cnt,a[mxn],num;
char s[mxn];
void solve(){
    cin>>s;
    n=strlen(s);
    for(int i=1;i<n;i++){
        if(s[i]=='-')num++;
        else a[++cnt]=num,num=0;
    }
    for(int i=1;i<=cnt;i++)cout<<a[i]<<' ';
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int T=1;while(T--)solve();
    return 0;
}

C - Move Segment

难度:橙


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mxn 500010
#define mp make_pair
int n,k,cnt,a[mxn],num;
int l[mxn],r[mxn];
string s;
void solve(){
    cin>>n>>k>>s;
    n=s.length(),s="0"+s;
    int lft=0,rgt=0;
    for(int i=1;i<=n;i++){
        if(s[i]=='1'&&s[i-1]=='0')lft=i;
        if(s[i]=='0'&&s[i-1]=='1')l[++cnt]=lft,r[cnt]=i-1;
    }
    if(s[n]=='1')l[++cnt]=lft,r[cnt]=n;
    for(int i=r[k-1]+1;i<=r[k-1]+1+r[k]-l[k];i++)swap(s[i],s[i-r[k-1]+l[k]-1]);
    for(int i=1;i<=n;i++)cout<<s[i];
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int T=1;while(T--)solve();
    return 0;
}

D - Strange Mirroring

难度:橙
倍增一下就行了。


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mxn 500010
#define mp make_pair
ll n,q,pos;
string s;
void solve(){
    cin>>s>>q;
    n=s.length(),s="0"+s;
    while(q--){
        cin>>pos;
        int opt=0;
        while(pos>n){
            ll len=n;
            while(len*2<pos)len<<=1;
            pos-=len,opt^=1;
        }
        if(opt){
            if(s[pos]>='a'&&s[pos]<='z')cout<<char(s[pos]+('A'-'a'))<<' ';        
            else cout<<char(s[pos]-('A'-'a'))<<' ';
        }
        else cout<<s[pos]<<' ';
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int T=1;while(T--)solve();
    return 0;
}

E - 1D Bucket Tool

难度:黄
并查集维护一下就行了。


#include<bits/stdc++.h>
using namespace std;
#define mxn 500010
int n,q,f[mxn],sze[mxn],col[mxn],l[mxn],r[mxn];
int fnd(int x){
    return x==f[x]?x:f[x]=fnd(f[x]);
}
void merge(int x,int c){
    int fx=fnd(x);
    int L=l[fx],R=r[fx];
    if(col[fx]==c)return;
    sze[col[fx]]-=R-L+1,col[fx]=c,sze[c]+=R-L+1;
    if(L>1){
        int fl=fnd(L-1);
        if(col[fl]==col[fx])f[fl]=fx,l[fx]=l[fl];
    }
    if(R<n){
        int fr=fnd(R+1);
        if(col[fr]==col[fx])f[fr]=fx,r[fx]=r[fr];
    }
}
void solve(){
    cin>>n>>q;
    for(int i=1;i<=n;i++)f[i]=col[i]=l[i]=r[i]=i,sze[i]=1;
    while(q--){
        int opt,x,c;cin>>opt;
        if(opt==1)cin>>x>>c,merge(x,c);
        else cin>>c,cout<<sze[c]<<'\n';
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    int T=1;while(T--)solve();
    return 0;
}

F - Exchange Game

难度:黄-绿
注意到 \(\rm N+M+L\leq12\),所以可以直接暴搜。


#include<bits/stdc++.h>
using namespace std;
#define mxn 4100
bool vis[mxn][mxn],win[mxn][mxn];
int m,n,p,a[15];
bool dfs(int x,int y){
    if(vis[x][y])return win[x][y];
    vis[x][y]=1;
    for(int i=0;i<n+m+p;i++){
        if((1<<i)&x){
            for(int j=0;j<n+m+p;j++)
                if(!((x|y)&(1<<j))&&a[j]<a[i])
                    if(!dfs(y,x^(1<<i)^(1<<j)))
                        return win[x][y]=1;
            if(!dfs(y,x^(1<<i)))return win[x][y]=1;
        }
    }
    return win[x][y]=0;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>m>>n>>p;
    for(int i=0;i<m+n+p;i++)cin>>a[i];
    if(dfs((1<<m)-1,((1<<n)-1)<<m))cout<<"Takahashi";
    else cout<<"Aoki";
    return 0;
}

G - Another Shuffle Window

难度:绿
先把 \(p_l\sim p_r\) 这一段与其他块的贡献求出来,\(p_l\sim p_r\) 内部的因为是随机打乱,所以顺序对和逆序对数量对半开。然后要求 \(n-k+1\) 个块的答案,用树状数组维护一下就行了。


#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mxn 200010
#define mod 998244353
#define I inline
ll n,k,a[mxn],tre[mxn],sum,sum0,ans;
I ll lowbit(ll x){
    return x&-x;
}
I void add(ll x,ll a){
    while(x<=n)tre[x]+=a,x+=lowbit(x);
}
I ll query(ll x){
    ll ret=0;
    while(x)ret+=tre[x],x-=lowbit(x);
    return ret;
}
I ll qpow(ll a,ll x){
    ll ret=1,base=a;
    while(x){
        if(x&1)ret=ret*base%mod;
        base=base*base%mod;
        x>>=1;
    }
    return ret;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++)cin>>a[i],sum0+=i-1-query(a[i]),add(a[i],1);
    memset(tre,0,sizeof(tre));
    for(int i=1;i<k;i++)sum+=i-1-query(a[i]),add(a[i],1);
    for(int i=k;i<=n;i++){
        sum+=k-1-query(a[i]),add(a[i],1);
        ans=(ans+sum0-sum)%mod;
        sum-=query(a[i-k+1])-1,add(a[i-k+1],-1);
    }
    ans=ans*qpow(n-k+1,mod-2)%mod;
    ans=(ans+k*(k-1)%mod*qpow(4,mod-2))%mod;
    cout<<ans;
    return 0;
}
posted @ 2024-11-17 21:45  nagato__yuki  阅读(39)  评论(0)    收藏  举报