1. 程式人生 > 其它 >牛客挑戰賽59

牛客挑戰賽59

前言

\(\texttt{p}\color{red}{\texttt{eterwuyihong}}\)\(\texttt{m}\color{red}{\texttt{yee}}\) 抓來打牛客。

小卡常小清新小原題場,出題人差不多得了。

\(\texttt{Rating Change:}{\color{green}{1578}} \to {\color{green}{1719}}\)
\(\Delta={\color{green}{\texttt{141}}}\qquad \texttt{rank:12}\)

A

結論挺一眼的,寫完不太敢交因為不會證。實際上就是把所有小木樁放在大木樁中間可以使每個小木樁的貢獻達到最大。

My Code
void solve(){
    int a,b;cin>>a>>b;
    int x=a/2,y=(a+1)/2;
    ll ans=1ll*x*y*b-1ll*x*b;
    cout<<ans<<'\n';
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int T;for(cin>>T;T--;) solve();
    return 0;
}

B

比較困難的閱讀理解題。注意每個人選定了出什麼時候就不會變了,所以預處理字首最終贏的是剪刀/石頭/布的概率是多少,以及字尾中從當前位置開始剪刀/石頭/布能贏的概率是多少。這樣每個人就是他出剪刀/石頭/布然後打贏了前面那個人再是能贏到底的概率乘起來。

My Code
const int MOD=998244353;
const int MAXN=1e5+10;
int ksm(int a,int p){
    int ret=1;while(p){
        if(p&1) ret=ret*a%MOD;
        a=a*a%MOD; p>>=1;
    }return ret;
}int inv(int x){return ksm(x,MOD-2);}
int sta[MAXN][3],pre[MAXN][3],suf[MAXN][3];
string s[MAXN];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;cin>>n;
    rep(i,1,n){
        cin>>s[i];
        int fm=0;rep(j,0,2) fm+=(s[i][j]=='1');
        fm=inv(fm);rep(j,0,2){
            if(s[i][j]=='1') sta[i][j]=fm;
            else sta[i][j]=0;
        }
    }
    rep(i,0,2) pre[1][i]=sta[1][i],pre[0][i]=1;
    rep(i,2,n){
        rep(j,0,2)
            pre[i][j]=(pre[i-1][j]*(1+MOD-sta[i][(j+2)%3])%MOD+pre[i-1][(j+1)%3]*sta[i][j]%MOD)%MOD;
    }
    rep(i,0,2) suf[n][i]=1;
    per(i,n-1,1){
        rep(j,0,2)
            suf[i][j]=suf[i+1][j]*(1+MOD-sta[i+1][(j+2)%3])%MOD;
    }
    rep(i,1,n){
        int cur=0;
        rep(j,0,2) cur=(cur+pre[i-1][(j+1)%3]*sta[i][j]%MOD*suf[i][j]%MOD)%MOD;
        cout<<cur<<' ';
    }
    return 0;
}

C

原題。為了保證奇偶,可以加上一個巨大的二的次冪,然後如果要奇數個數,那就直接查,不然以這個巨大的二的次冪為初始來查。然後直接 bitset 加上線性基就可以了。

My Code
const int MAXN=2010;
bool cmp(bitset<MAXN> x,bitset<MAXN> y){
    per(i,2000,0){
        if(x[i]==1&&y[i]==0) return 1;
        else if(x[i]==0&&y[i]==1) return 0;
    }return 1;
}
void print(bitset<MAXN> v){
    per(i,1999,0){
        if(v[i]){
            per(j,i,0) cout<<v[j];
            break;
        }if(!i) cout<<0;
    }
}
// void pprint(bitset<MAXN> v){
    // per(i,1999,0){
        // if(v[i]){
            // per(j,i,0) cerr<<v[j];
            // break;
        // }if(!i) cerr<<0;
    // }
// }
struct BASE{
    bitset<MAXN> p[MAXN];
    void insert(bitset<MAXN> x){
        for(int i=2000;i>=0;i--){
            if(x[i]==0) continue;
            if(!p[i].count()){p[i]=x;break;}x^=p[i];
        }
    }
    bitset<MAXN> qmax(bitset<MAXN> v){
        bitset<MAXN> ret=v;
        for(int i=2000;i>=0;i--){
            if(cmp(ret^p[i],ret))
                ret^=p[i];
        }return ret;
    }
}B;
bitset<MAXN> a[MAXN],vb,v0;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;cin>>n;
    rep(i,1,n) cin>>a[i],a[i][2000]=1,B.insert(a[i]);
    vb[2000]=1;
    bitset<MAXN> ans1=B.qmax(vb),ans2=B.qmax(v0);
    print(ans1);cout<<'\n';print(ans2);
    return 0;
}

D

E

F

G