zoukankan      html  css  js  c++  java
  • bjoi 2008 Gate Of Babylon 容斥原理

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 using namespace std;
     6 #define MAXN 20
     7 int n,T,m,p;
     8 int a[20];
     9 int factorial[100001],rev[100001];
    10 void init()
    11 {
    12     int i;
    13     factorial[0]=1;
    14     for(i=1;i<p;i++)
    15         factorial[i]=(long long)factorial[i-1]*i%p;
    16     rev[1]=1;
    17     for(i=2;i<p;i++)
    18         rev[i]=((-(p/i)*(long long)rev[p%i])%p+p)%p;
    19 }
    20 int calc_p(int x)
    21 {
    22     int ret=0;
    23     while(x)
    24     {
    25         ret+=x/p; x/=p;
    26     }
    27     return ret;
    28 }
    29 int my_pow(int x,int n)
    30 {
    31     int ans=1;
    32     while(n)
    33     {
    34         if(n&1) ans=(long long)ans*x%p;
    35         x=(long long)x*x%p;
    36         n>>=1;
    37     }
    38     return ans;
    39 }
    40 int calc(int x)
    41 {
    42     int ans=1,ret=0;
    43     while(x)
    44     {
    45         ret+=x/p; ans=(long long)ans*factorial[x%p]%p;
    46         x/=p;
    47     }
    48     ans=(long long)my_pow(factorial[p-1],ret)*ans%p;
    49     return ans;
    50 }
    51 
    52 int combination(int n,int m)
    53 {
    54     if(n<m) return 0;
    55     if(calc_p(n)!=calc_p(m)+calc_p(n-m))
    56         return 0;
    57     int s1=calc(n),s2=(long long)calc(m)*calc(n-m)%p;
    58     return (long long)s1*rev[s2]%p;
    59 }
    60 int solve()
    61 {
    62     int ans=0;
    63     m=m+n+1;
    64     n++;
    65     int top=(1<<T),i,j,cc,x;
    66     for(i=0;i<top;i++)
    67     {
    68         cc=0;
    69         x=m;
    70         for(j=0;j<T;j++)
    71         if(i&(1<<j)) 
    72         {
    73             cc++;
    74             x-=a[j];
    75         }
    76         if(cc%2==0) ans+=combination(x-1,n-1);
    77         else ans-=combination(x-1,n-1);
    78         ans=(ans%p+p)%p;
    79     }
    80     return ans;
    81 }
    82 
    83 int main()
    84 {
    85     scanf("%d%d%d%d",&n,&T,&m,&p);
    86     init();
    87     int i;
    88     for(i=0;i<T;i++) scanf("%d",a+i), a[i]++;
    89     printf("%d\n",solve());
    90     return 0;
    91     
    92 }

    思路:T很小 容斥原理

  • 相关阅读:
    SQL Server ->> Database Snapshot(数据块快照)
    SQL Server ->> Sparse File(稀疏文件)
    Linux ->> Sudo命令
    Linux ->> mkdir命令
    Linux ->> VMWare Workstation虚拟机里的UBuntu系统安装VMWare-tools
    Microsoft Office ->> 完整卸载Office 2007
    SQL Server ->> XML方法
    SQL Server ->> 更改服务器时区对SQL Server Agent服务器的影响
    分析java内存情况
    oracle 10g 11g 12c区别
  • 原文地址:https://www.cnblogs.com/myoi/p/2485827.html
Copyright © 2011-2022 走看看