Codeforces Round #721 (Div. 2)题解

比赛链接

wa得老惨了qwq,本来还以为只能一题,太惨了太惨了

 

A. And Then There Were K

给你一个n,求最大的k使得:

 

思路:求n二进制最高位对应的数-1

int n;
void solve()
{
    sd(n);
    int nn=n,val=1;
    while(nn)
    {
        val<<=1;
        nn>>=1;
    }
    val>>=1;
    pd(val-1);
}

 

B1. Palindrome Game (easy version)

给你一个01回文串

想要将这个字符串变为全1

两个操作:

1、将其中一个0变为1,花费1

2、当该字符串不是回文串且上一个操作不是2则可将该字符串反转,花费0

ALICE先手

最后花费最少的人获胜

思路:因为当前是回文,所以ALICE第一次必花费

cnt代表0的个数,当cnt是奇数代表中间是0

cnt为1时只能只有ALICE操作

当cnt为2时的操作为(1)ALICE花费1(2)BOB反转(3)ALICE花费1

当cnt为偶数且cnt>2时,BOB每次选择ALICE对应的位置的0变为1,直到cnt为2

当cnt为奇数时,ALICE选择中间的0变为1,然后风水轮流转,cnt变为偶数,自行代入上面的情况hhh

当cnt=1时花费为1:0

当cnt为奇数时花费差1

当cnt为偶数时花费差2

int n;
char s[maxn];
void solve()
{
    sd(n);
    sc(s+1);
    int cnt=0;
    rep(i,1,n)if(s[i]=='0')cnt++;
    if(cnt==1)puts("BOB");
    else if(cnt&1)puts("ALICE");
    else puts("BOB");
}

 

B2. Palindrome Game (hard version)

题意同上,只是原来的串不一定是回文串

int n,cnt,cnt1;
char s[maxn];
void solve()
{
    sd(n);
    sc(s+1);
    cnt=cnt1=0;
    rep(i,1,n)
    {
        if(s[i]=='1')continue;
        if(s[i]==s[n-i+1])cnt++;
        else cnt1++;
    }
    if(cnt1>=2||!cnt)
    {
        puts("ALICE");
        return;
    }
    if(cnt1==1)
    {
        if(cnt==1)puts("DRAW");
        else puts("ALICE");
        return;
    }
    if(cnt==1)puts("BOB");
    else if(cnt&1)puts("ALICE");
    else puts("BOB");
}

cnt为该位置为0且对应位置为0的个数

cnt1为该位置为0且对应位置为1的个数

当cnt为0时,按上一题解法

因为当cnt1>=3时,ALICE先每次都选择反转,BOB只能选择cnt1对应位置的0变为1,直到变为回文串,这时比分已经是0:cnt1了,BOB不可能反败为胜

当cnt1=2时,如果cnt为奇数,等到变为回文串时,ALICE是先手,具体同上一题;如果cnt为偶数,那么ALICE在第二次操作时选择将另一个cnt1的0变为1,然后变成的情况可参考上一题

当cnt1=1时,如果cnt为奇数,同上;否则ALICE第一步直接选择将这个0变为1,然后就变成的情况可参考上一题

 

C. Sequence Pair Weight

给一个长度为n的数组,区间[l,r]的值为在这区间内,ai=aj的对数

让你求对于所有的子区间的值和。

害,这题有点难讲啊,毕竟我也是混过去的(不会吧不会吧,不会有人要来hack我吧),暂时先只放代码吧

int n,a[maxn];
int l[maxn],pre[maxn],cnt[maxn];
ll ans,sum[maxn];
void solve()
{
    sd(n);ans=0;
    rep(i,1,n)sd(a[i]),l[i]=a[i];
    sort(l+1,l+1+n);
    int m=unique(l+1,l+1+n)-l-1;
    rep(i,1,m)pre[i]=0,sum[i]=0;
    ll sum1=0;
    rep(i,1,n)
    {
        int k=lower_bound(l+1,l+1+m,a[i])-l;
        ans+=sum1;
        sum[k]+=pre[k];
        ans+=sum[k];
        pre[k]=i;
        sum1+=sum[k];
    }
    plld(ans);    
}

 

posted @ 2021-05-21 00:53  芥么拉  阅读(82)  评论(0编辑  收藏  举报