zoukankan      html  css  js  c++  java
  • [CQOI 2018] 交错序列

    5298: [Cqoi2018]交错序列

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 59  Solved: 10
    [Submit][Status][Discuss]

    Description

    我们称一个仅由0、1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻的0)。例如,000,001
    ,101,都是交错序列,而110则不是。对于一个长度为n的交错序列,统计其中0和1出现的次数,分别记为x和y。
    给定参数a、b,定义一个交错序列的特征值为x^a*y^b。注意这里规定任何整数的0次幂都等于1(包括0^0=1)。
    显然长度为n的交错序列可能有多个。我们想要知道,所有长度为n的交错序列的特征值的和,除以m的余数。(m是
    一个给定的质数)例如,全部长度为3的交错串为:000、001、010、100、101。
    当a=1,b=2时,可计算31x02+21x12+21x12+21x12+11x22=10

    Input

    输入文件共一行,包含三个空格分开的整数n,a,b和m。
    1≤n≤10000000,0≤a,b≤45,m<100000000

    Output

    输出文件共一行,为计算结果。

    Sample Input

    3 1 2 1009

    Sample Output

    10
     
     
        x+y是定值,所以我们可以展开多项式算贡献。
        设 f(i,k,0/1) 为前i位中这一位是0/1的所有序列的1的个数的k次方的和,然后我们就可以矩阵直接转移了233.
     
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    int N,M,A,B,S[195],n,AB,T,ans,C[105][105],F[195];
    inline void ADD(int &x,int y){ x+=y; if(x>=M) x-=M;}
    inline int add(int x,int y){ x+=y; return x>=M?x-M:x;}
    inline int mul(int x,int y,const int ha){ return x*(ll)y%ha;}
    inline int ksm(int x,int y,const int ha){ int an=1; for(;y;y>>=1,x=mul(x,x,ha)) if(y&1) an=mul(an,x,ha); return an;}
    struct node{
    	ll a[49999];
    	inline void clear(){ memset(a,0,sizeof(a));}
    	inline void BASE(){ clear(); for(int i=0;i<T;i++) a[i*T+i]=1;}
    	node operator *(const node &u)const{
    		node r; r.clear();
    		for(int k=0;k<T;k++)
    		    for(int i=0;i<T;i++)
    		        for(int j=0;j<T;j++) r.a[i*T+j]+=a[i*T+k]*u.a[k*T+j];
    		for(int i=0;i<T;i++)
    		    for(int j=0;j<T;j++) r.a[i*T+j]%=(const int)M;
    		return r;
    	}
    }X,ANS;
    
    inline void build(){
    	C[0][0]=1;
    	for(int i=1;i<=100;i++){
    		C[i][0]=1;
    		for(int j=1;j<=i;j++) C[i][j]=add(C[i-1][j-1],C[i-1][j]);
    	}
    	
    	S[n=0]=1;
    	for(int i=1;i<=B;i++){
    		memcpy(F,S,sizeof(S));
    		memset(S,0,sizeof(S));
    		for(int j=0;j<=n;j++){
    			S[j]=add(S[j],mul(F[j],N,M));
    			S[j+1]=add(S[j+1],M-F[j]);
    		}
    		n++;
    	}
    	n+=A;
    	for(int i=n;i>=A;i--) S[i]=S[i-A];
    	fill(S,S+A,0);
    	
    	X.clear();
    	for(int i=0;i<AB;i++){
    		for(int j=i;j<AB;j++) X.a[i*T+j+AB]=C[j][i];
    		X.a[i*T+i]=X.a[(i+AB)*T+i]=1;
    	}
    }
    
    inline void calc(){
    	ANS.BASE();
    	for(;N;N>>=1,X=X*X) if(N&1) ANS=ANS*X;
    	for(int i=0;i<AB;i++) ans=add(ans,mul(add(ANS.a[i],ANS.a[i+AB]),S[i],M));
    }
    
    int main(){
    	scanf("%d%d%d%d",&N,&B,&A,&M),AB=A+B+1,T=AB<<1;
    	build(),calc();
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

      

  • 相关阅读:
    caffe常用层: batchNorm层和scale层
    简述configure、pkg-config、pkg_config_path三者的关系
    python删除list中元素的三种方法
    Leetcode 872. Leaf-Similar Trees
    Leetcode 508. Most Frequent Subtree Sum
    Leetcode 572. Subtree of Another Tree
    Leetcode 894. All Possible Full Binary Trees
    Leetcode 814. Binary Tree Pruning
    Leetcode 557. Reverse Words in a String III
    python 多维list声明时的小问题
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8874737.html
Copyright © 2011-2022 走看看