HNOI2002矩阵快速幂公交车路线
Posted Melacau----论一个蒟蒻的自我修养
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HNOI2002矩阵快速幂公交车路线相关的知识,希望对你有一定的参考价值。
仍然是学弟出的题目的原题@lher 学弟将题目改成了多组数据,n在ll范围内,所以我就只讲提高版的做法。
链接:https://www.luogu.org/problem/show?pid=2233
题意分析:看题目:)
解题思路:显然对于n为奇数的情况不存在任意路线。接下来我们进行观察数据,显然这题是要递推的。接下来通过暴力打表加手算,我们推出了这个公式:
f[i]=4*f[i-1]-2*f[i-2],f[1]=2,f[2]=8,然后构造对应矩阵进行矩阵快速幂即可得到答案。时间效率O(8Tlog(n))。
附AC代码:
#include<stdio.h> #include<iostream> #include<cmath> #include<cstring> #include<string> #include<algorithm> #define ll long long #define mod 10007 using namespace std; struct zxy{ ll a[2][2]; }jichu,a,b; ll n; inline ll in(){ ll x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) {if(ch==‘-‘) f=-1; ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } inline zxy mult(zxy a,zxy b){ zxy c; memset(c.a,0,sizeof(c.a)); for (int i=0; i<=1; ++i) for (int j=0; j<=1; ++j) for (int k=0; k<=1; ++k) c.a[i][j]+=(a.a[i][k]*b.a[k][j]+2*mod)%mod,c.a[i][j]=(c.a[i][j]+2*mod)%mod; return c; } inline zxy ksm(zxy a,ll k){ if (k==0) return jichu; if (k==1) return a; zxy tt=ksm(a,k>>1); if (k&1) return mult(a,mult(tt,tt)); return mult(tt,tt); } int main(){ int T=in(); memset(jichu.a,0,sizeof(jichu.a)); memset(b.a,0,sizeof(b.a)); memset(a.a,0,sizeof(a.a)); jichu.a[0][0]=jichu.a[1][1]=1; b.a[0][0]=2;b.a[1][0]=8; a.a[0][1]=1;a.a[1][0]=-2+mod,a.a[1][1]=4; while(T--){ n=in(); if (n&1) printf("0\n"); else{ n=n/2-2; if (n<2) printf("%lld\n",b.a[n][0]); else{ zxy ans=mult(ksm(a,n-1),b);printf("%lld\n",ans.a[1][0]);} } } return 0; }
以上是关于HNOI2002矩阵快速幂公交车路线的主要内容,如果未能解决你的问题,请参考以下文章