zoukankan      html  css  js  c++  java
  • CF954F Runner's Problem(动态规划,矩阵快速幂)

    CF954F Runner's Problem(动态规划,矩阵快速幂)

    题面

    CodeForces
    翻译:
    有一个(3 imes M)的田野
    一开始你在((1,2))位置
    如果你在((i,j))位置
    在不出界的前提下,可以走到((i+1,j),(i+1,j±1))
    (n)段障碍,障碍不能走
    询问从((1,2))到达((M,2))的方案数
    (n<=10^4,M<=10^{18})

    题解

    发现(M)的范围非常大
    很容易往矩阵快速幂的方向考虑
    如果知道上一行的方案,以及这一行的状态
    很容易可以列出转移矩阵
    所以,将所有的障碍段离散
    (3)行分离,检查当前段的障碍组成
    构建出转移矩阵
    分段做快速幂就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 11111
    #define MOD 1000000007
    inline ll read()
    {
        RG ll x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Maxtrix
    {
    	ll s[5][5];
    	void clear(){memset(s,0,sizeof(s));}
    	void init(){clear();s[1][1]=s[2][2]=s[3][3]=1;}
    	void M000(){clear();s[1][1]=s[1][2]=s[2][1]=s[2][2]=s[2][3]=s[3][2]=s[3][3]=1;}
    };
    Maxtrix operator*(Maxtrix a,Maxtrix b)
    {
    	Maxtrix ret;ret.clear();
    	for(int i=1;i<=3;++i)
    		for(int j=1;j<=3;++j)
    			for(int k=1;k<=3;++k)
    				ret.s[i][j]=(ret.s[i][j]+1ll*a.s[i][k]*b.s[k][j]%MOD)%MOD;
    	return ret;
    }
    Maxtrix fpow(Maxtrix a,ll b)
    {
    	Maxtrix s;s.init();
    	while(b){if(b&1)s=s*a;a=a*a;b>>=1ll;}
    	return s;
    }
    struct Block{ll l,r;int a;}blk[MAX];
    ll tot,top;
    ll S[MAX<<2];
    ll c[4][MAX<<1];
    ll n,Q;
    ll M;
    int main()
    {
    	n=read();M=read();
    	for(int i=1;i<=n;++i)
    	{
    		int a=read();ll l=read(),r=read();
    		S[++top]=l-1,S[++top]=r;
    		blk[++tot]=(Block){l,r,a};
    	}
    	S[++top]=1;S[++top]=M;
    	sort(&S[1],&S[top+1]);
    	top=unique(&S[1],&S[top+1])-S-1;
    	for(int i=1;i<=n;++i)
    	{
    		ll L=lower_bound(&S[1],&S[top+1],blk[i].l)-S;
    		ll R=lower_bound(&S[1],&S[top+1],blk[i].r)-S;
    		c[blk[i].a][L]++;c[blk[i].a][R+1]--;
    	}
    	Maxtrix ans;ans.clear();ans.s[2][1]=1;
    	ll ss[4];ss[1]=ss[2]=ss[3]=0;
    	for(int i=2;i<=top;++i)
    	{
    		ll len=S[i]-S[i-1];
    		Maxtrix now;now.M000();
    		for(int j=1;j<=3;++j)
    		{
    			ss[j]+=c[j][i];
    			if(ss[j])now.s[j][1]=now.s[j][2]=now.s[j][3]=0;
    		}
    		now=fpow(now,len);
    		ans=now*ans;
    	}
    	cout<<ans.s[2][1]<<endl;
    	return 0;
    }
    
    
  • 相关阅读:
    常见的线性结构
    Lambda表达式学习笔记
    Spring Security 入门 (二)
    Spring Security 入门(一)
    Eclipse 创建 Maven 项目
    初学 Spring MVC(基于 Spring in Action)
    蓝桥杯之入学考试
    Java 学习总结
    二叉搜索树和红黑树
    Detours 劫持
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8626655.html
Copyright © 2011-2022 走看看