[HNOI2011] Canon solution to a problem

Title Description

As we all know Canon is a polyphony of writing techniques, it inspired little more than big hair while listening to music canon, invented a new musical and write the rules. He sound scale is divided into n, and the music is divided into several segments. Each segment is a music sound scale 1 to n configuration, i.e., selection of the n number of scale from the scale played out simultaneously. To emphasize with Canon's different, he prescribed scale collection of any two clips it contains are different. Meanwhile, in order to maintain regularity music, he also provides the number of times a piece of music is played each scale is even. The question now is: I want to know the small fragment of music contains m a total number of species. Two pieces of music isoforms a and b if and only if after a segment can be rearranged b. For example: Assume that a

Is {{1,2}, {2,3}}, b is {{3,2}, {2,1}}, then a and b is the same kind of music. As many several, you just need to

100000007 answer result output module (prime number) of.

Input Format

Input.txt read data from the file, the input file is only one line, in particular with a space of two positive integers n and m, respectively represent the number of segments and the number of scale music. 20% of the data satisfies n, m≤5,50% of data satisfies n, m≤3000,100%

The data satisfies n, m≤1000000.

Output Format

Output.txt output file contains only a non-negative integer result kinds of digital to analog music 100000007.

 

Strong inclusion and exclusion problems.

The first question is intended to simplify this: from the set $ S = {1,2,3, ..., n} $ $ m $ selected subsets meet non-empty and the selected subset can have the same and guaranteed $ {1,2,3 ... n} $ is an even number of occurrences of each element .

The definition of the same kind of music topics given in the very annoying, so we ordered of the disorder, first calculated using the number of permutations, the final result is calculated and then divided by $ m! $ (Of course, can also be used directly in combination?).

Then consider the transfer. Defined $ f [i] $ program number is transferred to the second subset $ I $, satisfy all the conditions. If the first $ i-1 $ subsets have been identified, then this is an even nature, we can determine the first $ i $ subsets based on the number of times each element appears (only choose odd ago $ i-1 $ one appeared Elements). The total number of programs for $ A_ {2 ^ n-1} ^ {i-1} $.

This includes a number of non-empty and does not meet these two conditions are not the same collection. Consider the inclusion-exclusion out, if the first $ i $ subset is empty, then the first $ i-1 $ subsets is a legitimate program. So this part of the program number $ f [i-1] $.

We need to remove the presence of the same subset. $ I $ If the first subset and the second subset $ J $ repeat, then remove the first $ $ I $ J-th and $, and the remaining $ i-2 $ th program is legitimate, an amount of $ f [i-2 ] $. At this time, the first subset has $ I $ $ 2 ^ n-1- (i-2) $ kinds of programs, and that the same subset of $ I $ Location $ i-1 $ a, so this part of the program number $ f [i-2] \ times (i-1) \ times (2 ^ n-1- (i-2)) $.

$f[i]=A_{2^n-1}^{i-1}-f[i-1]-f[i-2]\times (i-1)\times (2^n-1-(i-2))$

Initialization $ f [0] = 1 $.

// real name diss a year do question when Chuan Mingming told me that the solution to a problem is not speaking up 
#include <cstdio> 
#include <iostream> 
#include <CString>
 a using  namespace std; 
typedef Long  Long LL;
 #define Re the Register
 const  int MOD = 1E8 + . 7 , N = 1000010 ; 
LL F [N], FAC, A [N], Side, n-, m; 
LL qpow (LL X, LL Y) 
{ 
    LL RES = . 1 ;
     the while (Y) 
    { 
        IF (Y & . 1 ) RES = RES * X% MOD; 
        X = X * X% MOD; 
        Y>>=1;
    }
    return res;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    fac=a[0]=f[0]=1;
    for(re int i=2;i<=m;i++)fac=fac*i%mod;
    fac=qpow(fac,mod-2);
    side=qpow(2,n)-1;
    for(re int i=1;i<=m;i++)a[i]=a[i-1]*(side-i+1)%mod;
    for(re int i=2;i<=m;i++)
    {
        f[i]=a[i-1]-f[i-1];
        f[i]-=(f[i-2]*(i-1)%mod*(side-i+2))%mod;
        f[i]=(f[i]%mod+mod)%mod;
    }
    cout<<f[m]*fac%mod<<endl;
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/Rorschach-XR/p/11330388.html