zoukankan      html  css  js  c++  java
  • zoj 3556 How Many Sets I 解题报告 <容斥原理>

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3556

      容斥原理:个数为n的集合子集个数为2^n。

     从子集中选k个的有序组合个数(子集可重复被选中)有 (2^n)^k=2^(n*k);

      故总数为S=2^(n*k);

      设S(x)为k个集合的有序组合的个数,这些集合都包含至少一个x。

     S(x1&x2)为k个集合的有序组合的个数,这些集合都包含至少一个x1和x2

      S(x1&x2&x3...xk)为k个集合的有序组合的个数,这些集合都包含至少一个x1,x2...xk。

     而  S(x)=(2^(n-1))^k =2^((n-1)*k);

     S(x1&x2)=(2^(n-2))^k=2^((n-2)*k);

     S(x1&x2&...&xi)=(2^(n-i))^k=2^((n-i)*k);

     由容斥原理知,我们要得到的就是

     S-(n,1)*S(x) + (n,2)*(S(x1&x2)-(n,3)*(S(x1&x2&x3)+....(-1)^i*(n,i)*S(x1&x2&...xi)...(-1)^n*(n,n)*S(x1&x2...&xn);

    化简得ans=(2^K-1)^N;

     1 #include <stdio.h>
    2 #include <math.h>
    3 typedef long long ll;
    4 const ll P=1000000007;
    5 ll ksm( ll a, ll b )
    6 {
    7 ll t=1;
    8 if( b==1 )
    9 return a;
    10 if( b==2 )
    11 return (a*a)%P;
    12 while( b>0 )
    13 {
    14 if( b&1 )
    15 {
    16 t*=a, t%=P;
    17 b--;
    18 }
    19 else
    20 {
    21 a*=a;
    22 a%=P;
    23 b/=2;
    24 }
    25 }
    26 return t;
    27 }
    28 int main( )
    29 {
    30 ll N, K;
    31 while( scanf( "%lld%lld", &N, &K ) != EOF )
    32 {
    33 ll m=ksm( 2, K );
    34 m--;
    35 ll ans=ksm( m, N );
    36 printf( "%lld\n", ans );
    37 }
    38 return 0;
    39 }
  • 相关阅读:
    【转】size_t和ssize_t
    WCF订票系统DEMO
    VS2008显示解决方案的方法
    一些好用的开源控件
    SQL 的Over 子句
    Sql2005高效分页语句
    使用winform的showdialog小心内存泄漏
    字符串连接类(Javascript)
    SharpZipLib 的使用
    浅谈持久化
  • 原文地址:https://www.cnblogs.com/jian1573/p/2374639.html
Copyright © 2011-2022 走看看