牛客挑战赛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;
}