zoukankan      html  css  js  c++  java
  • #矩阵乘法#洛谷 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]);
    }
    
  • 相关阅读:
    迭代器生成器和协程函数
    装饰器
    对haproxy.conf文件的增删改查
    函数基础
    深入理解python字符编码
    python字符串列表字典常用方法
    委托的使用
    数据库连接
    输入输出流
    泛型集合的使用
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13922363.html
Copyright © 2011-2022 走看看