[BZOJ 2839] count set

Title Description

A set of N elements there are 2 ^ N different subsets (containing empty set), is now set to be taken out in a number of these sets of 2 ^ N (at least one), such that the number of elements to their intersection K, Acquire the number of programs, the answer mode 1,000,000,007. (Oh ~ is a prime number)

Input Format

Line two integers N, K

Output Format

A behavioral answer.

Sample

Sample input

3 2

Sample Output

6

Data range and tips

Sample Description

Suppose the original set is {A, B, C}

Solution for the condition is satisfied: {AB, ABC}, {AC, ABC}, {BC, ABC}, {AB}, {AC}, {BC}

the data shows

To 100% of the data, 1≤N≤1000000; 0≤K≤N;

Ideas:

  You must make a table before doing the math. . . Consistent style solution to a problem, do not come to play a positive solution. . .

  Pre-knowledge: a collection of all of the sub-set of 2 ^ n number of each element appears, and then the selected subset scheme number 2 ^ (2 ^ n) -1 for each set if there is, first, because a Save selected from the set and not empty set is selected from a heavy, a count less.

  70% of the algorithm: DP so his mother is consequently capable , we will not count as a collection of n, k is the intersection of the program, then set out ah. . f [n] [k] is the answer, f [n] [k] = C (n, k) * f [nk] [0], meaning that the first elected k th reselection intersection is 0, then F [ n] [0] ye operator, it may be selected from the set of all numbers 2 ^ (2 ^ n) from the n -1-f [] [k ] obtained, however, f [n] [k] from the previous f [nk] [0] get, nothing wrong aftereffect did not have to, his mother would hit the table with you. . (WD great God here borrow Code)

 1 #include<cstdio>
 2 #define int long long
 3 const long long mod=1000000007;
 4 long long fac[1000005],inv[1000005],invv[1000005],x,y,n,k,f0[1000005],f[1000005];
 5 long long pow(long long b,long long t,long long modd,long long ans=1){
 6     for(;t;t>>=1 , b = b * b% mode) f (t & 1 ) ans = ans * b% mode;
7      return ans;
8  }
 9  Signed main () {
 10      scanf ( " %% LLD LLD " , & n & k);
11      fac [ 0 ] = inv [ 0 ] = invv [ 0 ] = f0 [ 0 ] = invv [ 1 ] = inv [ 1 ] = fac [ 1 ] = 1 ; f0 [ 1 ] = 2 ;
12      for ( int i = 2 ; to <= n; ++ i) fac [i] = fac [to-1 ] * as% v, invv [i] = (- v / i * invv [v% i]) v%, INV [i] = inv [i- 1 ] * invv [i]% v;
13      for ( int i = 1 ; i <= n; ++ i) {
 14          f0 [i] = (pow ( 2 , pow ( 2 , i, received 1 ), v) - 1 + v)% v;
15          for ( int j = 1 ; j <= i; j ++) F [j] = fac [i] * inv [j] *% v inv [ij]% f0 * v [ij]% v, f0 [ i] = (f 0 [i] -f [j] + v)% v;
16          f [ 0 ] = f0 [i];
17      }
 18      printf ( "%lld\n",(f[k]+mod)%mod);
19 }
View Code

  100% algorithm: Boy playing positive solution, before the election of k, n- = k, and now we are asking for is a collection of n, the intersection of 0 for the program, this time we again find the definition of a collection (I thought this died), a represents a determined collection element comprising a sum of the program, then there will be n sets to bloom like a flower, a variety of intersection , for example, two figures overlap the intermediate part E represents the intersection does not contain exactly two programs. Then we will require the size of a part (that is, the requirements of disjoint program), inclusion and exclusion seem to smell a hint of flavor. . . . 0 = Total intersection is - (> = 1) + (> = 2) .......

  years = Σ (-1) i * ^ C (n, i) * (2 ^ (2 ^ (ni)) - 1);

  PS: the so-called power of the power of recursion can be used, of course, you hit two quick power I have no idea. .

  

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int mn=1e6+20,mod=1e9+7;
int f[mn],fac[mn],inv[mn],n,k;
int qpow(int x,int k)
{
    int ans=1;
    for(;k;k>>=1,x=1ll*x*x%mod) if(k&1) ans=1ll*ans*x%mod;
    return ans;
}
long long C(int n,int m) {return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;}
int main()
{
    scanf("%d%d",&n,&k);fac[0]=1;
    for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%mod;
    inv[n]=qpow(fac[n],mod-2);
    for(int i=n;i;i--) inv[i-1]=1ll*inv[i]*i%mod;
    long long ans=0,tmp=C(n,k),tp=1;n-=k;
    int op=(n&1)?-1:1;
    for(int i=n;~i;i--)
    {
        ans=(ans+op*C(n,i)*tp%mod)%mod;
        tp=(tp*tp%mod+2*tp%mod)%mod;
        op=-op;
    }
    ans=ans*tmp%mod;
    printf("%lld\n",(ans+mod)%mod);
}
//for sigma i=0->n C(n,i)(2^(2^(n−i))−1)
/*
g++ 1.cpp -o 1
./1
4 1
*/
View Code

 

Guess you like

Origin www.cnblogs.com/starsing/p/11129307.html