UVA110806&&POJ3904

来源:互联网 发布:c语言char占几个字节 编辑:程序博客网 时间:2024/06/10 22:52

UVA11806

在m*n的格子里面放k个东西,保证第一行第一列最后一行最后一列一定要有东西,问放法

赤裸裸的考虑反面的各种情况:

1.第一行||最后一行||第一列||最后一列没有

2.第一行&&最后一行||第一列&&最后一列||然后某一行&&某一列木有的组合

3.第一行&&最后一行&&某一列

4.第一行&&最后一行&&第一列&&最后一列

然后ANS-上面的容斥过程就OK了,不用位运算,直接去算,我还是写的来的诶~ORZ。

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const long long mod=1000007;const long long maxn=505;long long C[maxn][maxn];long long m,n,k;void init(){    memset(C,0,sizeof(C));    C[0][0]=1;    for(int i=1;i<=500;i++)    {        C[i][0]=C[i][i]=1;        for(int j=1;j<=i;j++)        {            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;        }    }}int main(){    int t;    int cas=0;    init();    cin>>t;    while(t--)    {        cin>>m>>n>>k;        long long ans,res;        if(k>m*n||k<2)        {            ans=0;        }        else        {            ans=(2*C[(m-1)*n][k]+2*C[m*(n-1)][k])%mod;//第一行||最后一行||第一列||最后一列没有            res=((C[(m-2)*n][k]+C[m*(n-2)][k])%mod+4*C[(m-1)*(n-1)][k]%mod)%mod;            ans=(ans-res+mod)%mod;            ans=(ans+2*C[(m-2)*(n-1)][k])%mod;            ans=(ans+2*C[(m-1)*(n-2)][k])%mod;            ans=(ans-C[(m-2)*(n-2)][k]+mod)%mod;            ans=(C[m*n][k]-ans+mod)%mod;        }         printf("Case %d: %lld\n",++cas,ans);    }    return 0;}

POJ 3904

给N个数,选4个 求gcd(a,b,c,d)=1的组数。

没说要两两互质,然后就乖乖的对N个数进行质因子分解并且统计数目,这样求出来的总和是gcd>1的数目,然后拿C(n,4)-当前得到的总和就好。

还是套那个位运算的模板,但是目测还是没有理解透彻位运算,好忧桑,即使知道如何容斥都好难敲出来T T,好想有人教我位运算是咋个进行容斥的,当然更希望有人帮我讲解一下DFS是咋个写的ORZ ...

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const long long N=10005;long long n;long long ans[N];void init(){    for(long long i=4;i<N;i++)    {        ans[i]=(i)*(i-1)*(i-2)*(i-3)/24;    }}long long  vis[N],num[N];long long  prime[N];long long  cnt;void gao(long long  x){    cnt=0;    for (long long  i=2;i*i<=x;i++)    {        if(x%i==0)        {            prime[cnt++]=i;            while (x%i==0)                x/=i;        }    }    if (x>1)    prime[cnt++]=x;    for (long long  i=1;i<(1<<cnt);i++)    {        long long  flag=0,tmp=1;        for (long long  j=0;j<cnt;j++)        {            if ((1<<j)&i)            {                tmp*=prime[j];                flag++;            }        }        vis[tmp]++;//记录当前因子个数        num[tmp]=flag;////记录当前因子是由多少个素因子组成    }}int  main(){    init();    while (scanf("%I64d",&n)!=EOF)    {        memset(vis,0,sizeof(vis));        memset(num,0,sizeof(num));        long long a;        for(long long i=0;i<n;i++)        {            cin>>a;            gao(a);        }        long long res=0;        for(long long i=1;i<(long long )N;i++)        {            if(vis[i]>0)            {                if(num[i]&1)                    res+=ans[vis[i]];                else                    res-=ans[vis[i]];            }        }        cout<<ans[n]-res<<endl;    }    return 0;}


0 0
原创粉丝点击