Codeforces Round 493 (Div.1)

终于上红啦.....................

我感觉.....真开心

ACB这个顺序真心有毒

以及那些人到底怎么A题挂的一片.............

我真不明白.....................

A题:

区间操作:

区间翻转(0变1,1变0),代价y

区间反转(110-->011),代价x

问变成全1的最小代价

做法:

首先连续的一起操作肯定不会有问题

所以变成一个

01010101...这样的串(第一位可能是1,反正01相间就对了)

然后翻转=删除一个01

设0的数量是n

那么要么y*n

要么是x*(n-1)+y

第二种情况要求n!=0

C题

*吐槽:

这场比赛真有毒,B和C都是输入n输出一个数....

然后.....先做C后做B..............

B想了半天不会做也是醉了...............

然后C题.........

C题弱智错误WA了两发

----------------------------

题意:

n*n的格子,每个颜色是RGB三种颜色之一(任意放)

如果其中一行或者一列是相同颜色就是"好的"

问一共3n*n种方案里面,有多少种是好的

做法:

标准的容斥做法

三种情况:

一共有k行颜色相同,方案数是(注意到这k行可以互不相同)

3k*3n(n-k)*C(n,k)*(-1)k-1

一共有k列颜色相同,也是上述的方案数

一共有i行j列颜色相同

注意到这i行j列一定颜色相同

方案数是

3*3(n-i)(n-j)*C(n,i)*C(n,j)*(-1)i+j

我们可以利用二项式定理来解决这个问题

我们可以这么计算

3*C(n,i)*(-1)i*C(n,j)*(3(n-i))(n-j)*(-1)j

所以后面的东西可以用二项式定理

j = 1 ... n改为j = 0 ... n就是标准的二项式定理(3(n-i)-1)n的内容

所以我们直接用二项式定理即可

具体式子看代码.............

B题

I,V,X,L一共有4个罗马字符

(I=1 V=5 X=10 L=50)

用n个,能得到多少种数字

注意:我们不在意罗马字符的顺序,换而言之,IX=XI=11

做法:

我们在n<=100的时候直接暴力,a个I,b个V,c个X,n-a-b-c个L这样

复杂度O(n4)

在n>100的时候

我们思考,首先所有数-=n

那么就只有0,4,9,49这些数字构成的

那么假设无限个,我们就能构成

24以上的所有数和24以下的一部分数

我们思考,所有数=50n-它本身

那么只有0,-40,-45,-49构成

那么假设有无限个,我们能构成-(40*49)以下的所有数

两端的dp就行了

===================

A题

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
char a[300005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,x,y;
    scanf("%d%d%d",&n,&x,&y);
    scanf("%s",a);
    int i;
    char last_char='';
    int zeros=0;
    for (i=0;i<n;i++)
    {
        if (a[i]==last_char)
        {
            continue;
        }
        last_char=a[i];
        if (a[i]=='0')
        {
            zeros++;
        }
    }
    if (zeros==0)
    {
        puts("0");
        return 0;
    }
    cout<<min(zeros*(long long)y,y+(long long)(zeros-1)*x)<<endl;
    return 0;
}

C题

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int modo=998244353;
int power(int x,int y)
{
    if (y==0) return 1;
    int t=power(x,y/2);
    t=(long long)t*t%modo;
    if (y%2==1) t=(long long)t*x%modo;
    return t;
}
int pow3[100005];
int pow3_head[100005];
int fact[1000005];
int anti_fact[1000005];
int power3(long long x)
{
    x%=(modo-1);
    return (long long)pow3_head[x/100000]*pow3[x%100000]%modo;
}
int c(int n,int x)
{
    return (long long)fact[n]*anti_fact[x]%modo*anti_fact[n-x]%modo;
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int i;
    pow3[0]=1;
    for (i=1;i<=100000;i++)
    {
        pow3[i]=(long long)pow3[i-1]*3%modo;
    }
    pow3_head[0]=1;
    for (i=1;i<=100000;i++)
    {
        pow3_head[i]=(long long)pow3_head[i-1]*pow3[100000]%modo;
    }
    fact[0]=1;
    for (i=1;i<=1000000;i++)
    {
        fact[i]=(long long)fact[i-1]*i%modo;
    }
    anti_fact[1000000]=power(fact[1000000],modo-2);
    for (i=1000000;i>=1;i--)
    {
        anti_fact[i-1]=(long long)anti_fact[i]*i%modo;
    }
    int n;
    scanf("%d",&n);
    int ans=0;
    int p=-1;
    for (i=1;i<=n;i++)
    {
        p*=-1;
        ans=(ans+p*(long long)c(n,i)*power3(i)%modo*power3((long long)(n-i)*n))%modo;
        ans=(ans+p*(long long)c(n,i)*power3(i)%modo*power3((long long)(n-i)*n))%modo;
        ans=(ans-p*(long long)c(n,i)*3%modo*power3((long long)(n-i)*n))%modo;
    }
    p=-1;
    for (i=1;i<=n;i++)
    {
        p*=-1;
        ans=(ans+p*c(n,i)*(long long)3*power(power3(n-i)-1,n))%modo;
    }
    ans=(ans+modo)%modo;
    printf("%d
",ans);
    return 0;
}

B题

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int ans[50005];
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n;
    scanf("%d",&n);
    if (n<=100)
    {
        int i,j,k,l;
        for (i=0;i<=n;i++)
        {
            for (j=0;i+j<=n;j++)
            {
                for (k=0;i+j+k<=n;k++)
                {
                    l=n-i-j-k;
                    ans[i+j*5+k*10+l*50]=true;
                }
            }
        }
        int cnt=0;
        for (i=0;i<=50000;i++)
        {
            if (ans[i]) cnt++;
        }
        printf("%d
",cnt);
        return 0;
    }
    int i;
    long long min_val=n+24;
    long long max_val=(long long)n*50-1960;
    for (i=0;i<=49;i++)
    {
        int j,k;
        for (j=0;i+j<=49;j++)
        {
            for (k=0;i+j+k<=49;k++)
            {
                ans[i*40+j*45+k*49]=true;
            }
        }
    }
    long long f_ans=max_val-min_val+1;
    for (i=0;i<1960;i++)
    {
        if (ans[i]) f_ans++;
    }
    f_ans+=12;
    cout<<f_ans<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/absi2011/p/9261330.html