Codechef CNTL Counting is life

Link
第一问如果\(2|k-n\)那么答案就是\(2^k-1\),否则就是\(2^k-2\)
第二问是一个可重排列的模型,考虑EGF。
我们对于一个数的出现次数的奇偶性有要求,符合条件的就是EGF就是\(\operatorname{sh}x\)\(\operatorname{ch}x\)
因此若\(2|k-n\)那么答案为\([x^n]\operatorname{sh}^kx\),否则答案为\([x^n]\operatorname{sh}^{k-1}x\operatorname{ch}x\)

#include<cctype>
#include<cstdio>
const int N=100007,P=1000000007;
int fac[N],ifac[N];
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
void dec(int&a,int b){a-=b,a+=a>>31&P;}
int mul(int a,int b){return 1ll*a*b%P;}
int pow(int a,int k){a+=a>>31&P;int r=1;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;}
int C(int n,int m){return n<m? 0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
int main()
{
    fac[0]=1;for(int i=1;i<=100000;++i) fac[i]=mul(fac[i-1],i);
    ifac[100000]=pow(fac[100000],P-2);for(int i=100000;i;--i) ifac[i-1]=mul(ifac[i],i);
    for(int T=read(),n,k,ans;T;--T)
    {
	n=read(),k=read(),ans=0;
	if((n^k)&1)
	{
	    for(int i=0;i<k;++i) (i&1? dec:inc)(ans,mul(C(k-1,i),pow(k-i-i,n)+pow(k-i-i-2,n)));
	    printf("%d %d\n",pow(2,k)-2,mul(ans,pow(pow(2,k),P-2)));
	}
	else
	{
	    for(int i=0;i<=k;++i) (i&1? dec:inc)(ans,mul(C(k,i),pow(k-i-i,n)));
	    printf("%d %d\n",pow(2,k)-1,mul(ans,pow(pow(2,k),P-2)));
	}
    }
}
posted @ 2020-04-14 15:24  Shiina_Mashiro  阅读(136)  评论(0编辑  收藏  举报