• #矩阵乘法#洛谷 5343 【XR-1】分块


    题目


    分析

    考虑dp,(dp[i]=sum dp[i-j])
    既然(j)很小,那么这显然可以用矩阵乘法优化


    代码

    #include <cstdio>
    #include <cctype>
    #include <bitset>
    #include <cstring>
    #define rr register
    using namespace std;
    const int N=101,mod=1000000007;
    bitset<N>cnt1,cnt2; long long n;
    struct maix{int p[N][N];}ANS,A;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void Mo(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
    inline maix mul(maix A,maix B){
    	rr maix C;
    	memset(C.p,0,sizeof(C.p));
    	for (rr int i=1;i<N;++i)
    	for (rr int j=1;j<N;++j)
    	for (rr int k=1;k<N;++k)
    	    Mo(C.p[i][j],1ll*A.p[i][k]*B.p[k][j]%mod);
    	return C;
    }
    signed main(){
        scanf("%lld",&n),ANS.p[1][0]=1;
    	for (rr int T=iut();T;--T) cnt1[iut()]=1;
    	for (rr int T=iut();T;--T) cnt2[iut()]=1; cnt1&=cnt2; 
    	for (rr int i=1;i<N;++i)
    	    if (cnt1[i]) A.p[N-i][N-1]=1;
    	for (rr int i=2;i<N;++i) A.p[i][i-1]=1;
    	for (rr int i=1;i<N;++i)
    	for (rr int j=0;j<i;++j) if (cnt1[i-j])
    	    Mo(ANS.p[1][i],ANS.p[1][j]);
    	if (n<N) return !printf("%d",ANS.p[1][n]);
    	for (n-=N-1;n;n>>=1,A=mul(A,A))
    	    if (n&1) ANS=mul(ANS,A);
    	return !printf("%d",ANS.p[1][N-1]);
    }
    
  • 相关阅读:
    零点起飞学Word与Excel高效办公实战与技巧
    C语言核心技术(原书第2版)
    完全精通Nuendo电脑音乐及音频制作:精细操作与实践指南
    1035.找出直系亲属(floyd)
    1033.继续XXX定律
    1034.寻找大富翁
    1032.ZOJ问题
    1029.魔咒词典
    1031.XXX定律
    1028.继续畅通工程
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13922363.html
Copyright © 2020-2023  润新知