zoukankan      html  css  js  c++  java
  • 【csp模拟赛3】bridge.cpp--矩阵加速递推

    题目描述

    穿越了森林,前方有一座独木桥,连接着过往和未来(连接着上一题和下一题...)。 这座桥无限长。

    小 Q 在独木桥上彷徨了。他知道,他只剩下了 N 秒的时间,每一秒的时间里,他会向 左或向右移动一步。 N 秒之后,小 Q 恰在桥上某一特定位置,且他每两次经过此位置的时间间隔不会超过 M 秒。 那么问题来了,这 N 秒的时间里,小 Q 的路线总共会有多少种可能的形式。

    输入

    文件第一行两个正整数 N、M,如题目所描述

    输出

    输出一个整数,表示可能的路线数量最终模 1000000007 的结果

    样例输入 1

    4 2

    样例输出 1

    4

    样例输入2

    10 6

    样例输出 2

    184

    数据规模与约定 对于 30% 的测试数据, 2 <=N<=100 ; 对于全部测试数据, 9 2 <=N <=10 , M <=N 且 M <=100 。保证 N 和 M 都是偶 数。资源限制 每个测试点空间限制 256MB,时间限制 1s。 一共 20 个测试点,满分 100 分。

    思想:

        矩阵加速递推

    若只考虑从最终到达的特定位置向单一方向出发,令 F(x, y)表示在一次出行内离开最终 位置 x 个单位时间时你恰好处于距最终位置 y 个单位距离的方案数。易得转移方程: F(1,1)=1,F(x,y)=F(x-1,y-1)+F(x-1,y+1). 预处理 F 数组,时间复杂度 O(M2 )。 由此可直接通过递推简便地得到答案,时间复杂度 O(NM),可通过 60%的测试数据。 利用矩阵乘法优化,可将时间复杂度优化至 O(M^3*log2N),通过全部测试数据。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define mod 1000000007
    using namespace std;
    
    int n,m;
    long long f[200][200];
    struct node {
    	long long a[200][200];
    	
    }a,c;
    
    inline node MUL(node a,node b) {
    		node wfx;
    		memset(wfx.a,0,sizeof(c.a));
    		for(int i = 1;i <= m >> 1;i ++)
    			for(int j = 1;j <= m >> 1;j ++)		
    				for(int k = 1;k <= m >> 1;k ++)
    					wfx.a[i][j] = (wfx.a[i][j] + a.a[i][k] * b.a[k][j]) % mod;
    		return wfx;
    	}		
    
    inline void KSM(int y) {
    	for( ; y ; y >>= 1,a = MUL(a,a))
    		if(y & 1) c = MUL(c,a);
    }
    
    
    int main()
    {
    	#ifdef yilnr
    	#else
    	freopen("bridge.in","r",stdin);
    	freopen("bridge.out","w",stdout);
    	#endif
    	scanf("%d%d",&n,&m);
    	f[1][1]=1;
    	for(int i=1;i<=m;i++)
    	  for(int j=1;j<=(m>>1);j++)
    	  {
    	     f[i+1][j+1]=(f[i+1][j+1]+f[i][j])%mod;
    		 f[i+1][j-1]=(f[i+1][j-1]+f[i][j])%mod;
    	  }
    	for(int i=1;i<=(m>>1)-1;i++)a.a[i+1][i]=1;
    	for(int i=1;i<=(m>>1);i++)c.a[i][i] = 1,a.a[1][i]=(f[i<<1][0]<<1)%mod;
    	KSM(n>>1);
    	printf("%d",c.a[1][1]);
    }
    
  • 相关阅读:
    MTK 关闭耳机调至最大音量时,提示损伤听力
    MTK LCM的添加
    chmod chown
    ubuntu14.04设置静态IP
    MTK NTP和NITZ更新时间的问题
    Rk3288 双屏异显单触摸
    MTK 修改默认时区
    MTK 屏幕旋转90度
    MTK WIFI底部加入返回按钮
    MTK 自定义按键添加广播
  • 原文地址:https://www.cnblogs.com/yelir/p/11564358.html
Copyright © 2011-2022 走看看