zoukankan      html  css  js  c++  java
  • 【洛谷P3193】【HNOI2008】—GT考试(矩阵快速幂)

    传送门

    对一个串建AcAc自动机(闲得蛋疼)
    然后只需要保证不走到最后一个节点就可以了
    矩阵快速幂即可

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>
    #define chemx(a,b) ((a)<(b)?(a)=(b):0)
    #define chemn(a,b) ((a)>(b)?(a)=(b):0)
    int mod;
    inline int add(int a,int b){return (a+=b)>=mod?a-mod:a;}
    inline void Add(int &a,int b){(a+=b)>=mod?a-=mod:0;}
    inline int dec(int a,int b){return (a-=b)<0?a+mod:a;}
    inline void Dec(int &a,int b){(a-=b)<0?a+=mod:0;}
    inline int mul(int a,int b){return 1ll*a*b%mod;}
    inline void Mul(int &a,int b){a=1ll*a*b%mod;}
    inline int ksm(int a,int b,int res=1){for(;b;b>>=1,Mul(a,a))(b&1)&&(Mul(res,a),1);return res;}
    inline int Inv(int x){return ksm(x,mod-2);}
    cs int N=22;
    int len;
    struct mat{
    	int a[N][N];
    	mat(){memset(a,0,sizeof(a));}
    	friend inline mat operator *(cs mat &a,cs mat &b){
    		mat c;
    		for(int i=0;i<=len;i++)
    		for(int k=0;k<=len;k++)
    		for(int j=0;j<=len;j++)
    		Add(c.a[i][j],mul(a.a[i][k],b.a[k][j]));
    		return c;
    	}
    };
    namespace ac{
    	int nxt[N][11],fail[N],tot;
    	inline void insert(char *s){
    		int p=0;
    		for(int i=1,len=strlen(s+1);i<=len;i++){
    			int c=s[i]-'0';
    			if(!nxt[p][c])nxt[p][c]=++tot;
    			p=nxt[p][c];
    		}
    	}
    	inline void buildac(){
    		queue<int> q;
    		for(int i=0;i<=9;i++){
    			if(nxt[0][i])q.push(nxt[0][i]);
    		}
    		while(!q.empty()){
    			int u=q.front();q.pop();
    			for(int i=0;i<=9;i++){
    				int v=nxt[u][i];
    				if(!v)nxt[u][i]=nxt[fail[u]][i];
    				else fail[v]=nxt[fail[u]][i],q.push(v);
    			}
    		}
    	}
    	inline mat getmat(){
    		mat c;
    		len=tot-1;
    		for(int i=0;i<tot;i++){
    			for(int j=0;j<=9;j++){
    				if(nxt[i][j]!=tot)Add(c.a[i][nxt[i][j]],1);
    			}
    		}
    		return c;
    	}
    }
    int n,m,k;
    char s[N];
    int main(){
    	#ifdef Stargazer
    	freopen("lx.cpp","r",stdin);
    	#endif
    	n=read(),m=read(),mod=read();
    	scanf("%s",s+1);
    	ac::insert(s),ac::buildac();
    	mat a=ac::getmat();
    	mat now;
    	now.a[0][0]=1;
    	for(;n;n>>=1,a=a*a)if(n&1)now=now*a;
    	int res=0;
    	for(int i=0;i<=len;i++)Add(res,now.a[0][i]);
    	cout<<res;
    }
    
  • 相关阅读:
    Android 逐帧动画
    MAP getLastKnownLocation()返回null的解决
    大数取余
    (a^b)%c和(a/b)%c
    HDU1046 Gridland
    顺序入栈的出栈方法种数
    HDU1021 Fibonacci Again
    HDU1019 Least Common Multiple
    HDU1018 Big Number
    HDU1013 Digital Roots
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328477.html
Copyright © 2011-2022 走看看