zoukankan      html  css  js  c++  java
  • [BZOJ 3823]定情信物

    题面

    定情信物

    题解

      这题主要考高中物理和数学。
      首先定义 (f[i][j]) 表示 (i) 维超立方体中第 (j) 维元素的数量,根据实际意义,我们可以推出递推式: (f[i][j]=2cdot f[i-1][j]+f[i-1][j-1])

       (i) 维超立方体是由 (i!-!1) 维超立方体平移得来的,那么第 (j) 维元素来源为原来的第 (j) 维元素并复制了一份,加上原来的第 (j!-!1) 维元素通过平移而新构成了一部分。——Ezio

      然后我们考虑其组合意义,发现 (f[i][j]) 表示把 (i) 个元素分为 (j) 份,每份第一个元素贡献为 (1) ,其它元素贡献为 (2) 。那么我们就可以定义 (g[i][j]) 表示把 (i) 个元素分为 (j) 份,每个元素贡献都为 (2) ,也就是说 (g[i][j]=2^icdot C_i^j) ,并且有 (g[i][j]=2^jcdot f[i][j]) ,那么 (f[i][j]=2^{i-j}cdot C_i^j) ,然后就能直接算了,注意要用 ( ext{Lucas})

    代码

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    const int maxn=1e7+3;
    int n,MOD;
    int bin[maxn];
    int Fac[maxn];
    int Inv[maxn];
    inline int Pow(int x,int k){
    	int ans=1;
    	for(;k;x=x*1ll*x%MOD,k>>=1)
    		if(k&1)ans=ans*1ll*x%MOD;
    	return ans;
    }
    inline int C(int n,int m){return Fac[n]*1ll*Inv[m]%MOD*Inv[n-m]%MOD;}
    inline int Lucas(int n,int m){
    	if(n<MOD && m<MOD)
    		return n<m ? 0 : C(n,m);
    	const int nn=n%MOD,mm=m%MOD;
    	return nn<mm ? 0 : C(nn,mm)*1ll*Lucas(n/MOD,m/MOD)%MOD;
    }
    int main(){
    	scanf("%d%d",&n,&MOD);
    	int M=std::min(MOD-1,n);
    	for(int i=Fac[0]=1;i<=M;++i)
    		Fac[i]=Fac[i-1]*1ll*i%MOD;
    	Inv[M]=Pow(Fac[M],MOD-2);
    	for(int i=M-1;~i;--i)
    		Inv[i]=Inv[i+1]*1ll*(i+1)%MOD;
    	for(int i=bin[0]=1;i<=n;++i)
    		bin[i]=(bin[i-1]<<1)%MOD;
    	int ans=0;
    	for(int i=0;i<=n;++i)
    		ans^=bin[n-i]*1ll*Lucas(n,i)%MOD;
    	printf("%d
    ",ans);
    	return 0;
    }
    
    HAHA
  • 相关阅读:
    class 类添加属性
    Ajax请求数据data被JSON.stringify()的数据django解码过程
    Python之浏览器的前进或后退
    滚动条-智能等待-富文本
    Python之阶乘代码
    Python之用型号构成一个三角形代码
    C# Dictionary
    使用C#创建Windows服务
    sql取出每月最早的上报的数据
    mvc NPOI导入读取Excel文件
  • 原文地址:https://www.cnblogs.com/hahamengbier/p/bzoj-3823.html
Copyright © 2011-2022 走看看