• LG5337/BZOJ5508 「TJOI2019」甲苯先生的字符串 线性动态规划+矩阵加速


    问题描述

    LG5337

    BZOJ5508


    题解

    (opt_{i,j}(i in [1,n],j in [1,26]))代表区间([1,i]),结尾为(j)的写法。

    (exist_{i,j}(i,j in [1,26]))代表((i,j))能否前后相邻,如果为(1),则不能。

    则有

    [opt_{i,j}=sum_{k=1}^{26} opt_{i-1,k}(exist_{k,j}=0) ]

    发现(n le 10^{15}),就这样递推肯定不行,所以矩阵优化

    矩阵(base)(26 imes 26)的,(base_{i,j}=1-exist_{i,j})


    (mathrm{Code})

    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    template <typename Tp>
    void read(Tp &x){
    	x=0;char ch=1;int fh;
    	while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    	if(ch=='-'){
    		fh=-1;ch=getchar();
    	}
    	else fh=1;
    	while(ch>='0'&&ch<='9'){
    		x=(x<<1)+(x<<3)+ch-'0';
    		ch=getchar();
    	}
    	x*=fh;
    }
    
    const int mod=1000000007LL;
    
    char s[100007];
    int len,n;
    int exist[27][27];
    
    int chk(char c){
    	return c-'a'+1;
    }
    
    struct Mat{
    	int a[27][27],n;
    	Mat(){
    		n=26;memset(a,0,sizeof(a));
    	}
    }base,ans;
    
    Mat Mul(Mat a,Mat b){
    	int q=a.n;
    	Mat ret;
    	for(int i=1;i<=q;i++){
    		for(int j=1;j<=q;j++){
    			for(int k=1;k<=q;k++){
    				ret.a[i][j]=(ret.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
    			}
    		}
    	}
    	return ret;
    }
    
    Mat ksm(Mat x,int p){
    	Mat ret;
    	for(int i=1;i<=26;i++) ret.a[i][i]=1;
    	while(p){
    		if(p&1) ret=Mul(ret,x);p>>=1;
    		x=Mul(x,x);
    	}
    	return ret;
    }
    
    int sum;
    
    signed main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>(s+1);
    	if(n==1){
    		puts("1");return 0;
    	}
    	len=strlen(s+1);
    	for(int i=2;i<=len;i++){
    		int xx=chk(s[i]),yy=chk(s[i-1]);
    		exist[yy][xx]=1;
    	}
    	for(int i=1;i<=26;i++){
    		ans.a[1][i]=1;
    		for(int j=1;j<=26;j++){
    			if(!exist[i][j]) base.a[i][j]=1;
    		}
    	}
    	ans=Mul(ans,ksm(base,n-1));
    	for(int i=1;i<=26;i++){
    		sum=(sum+ans.a[1][i])%mod;
    	}
    	cout<<sum<<endl;
    	return 0;
    }
    
  • 相关阅读:
    小鸡

    一个初中生到程序员的辛酸经历
    一些美国科幻片名字
    jspsql论坛分页的例子
    通过反射动态使用Java类
    用session保持一个数组
    转载-一些动态加载类的文章
    一个有ajax功能的jsp
    通过反射动态使用Java类(转)
  • 原文地址:https://www.cnblogs.com/liubainian/p/11519310.html
Copyright © 2020-2023  润新知