Read the program below carefully then answer the question.
pragma comment(linker, "/STACK:1024000000,1024000000")
include
include
include
include
include
include
const int MAX=100000*2;
const int INF=1e9;
int main()
{
int n,m,ans,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
ans=0;
for(i=1;i<=n;i++)
{
if(i&1)ans=(ans2+1)%m;
else ans=ans2%m;
}
printf("%d\n",ans);
}
return 0;
}
可以按照奇偶分类,找到偶数项或是奇数项的公式然后直接算。
也可以直接两种转移矩阵写出来
假设A,B分别是奇数和偶数的转移矩阵,虽然他们是交替的,我们不能直接用快速幂,但是可以利用结合律,将BA看做整体算。本质和先算出偶数项公式一样。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<bitset>
#include<cmath>
#include<set>
#include<unordered_map>
#define fo(i,a,b) for (ll (i)=(a);(i)<=(b);(i)++)
#define fd(i,b,a) for (ll (i)=(b);(i)>=(a);(i)--)
#define mk(x,y) make_pair((x),(y))
//#define A puts("Yes")
//#define B puts("No")
using namespace std;
typedef double db;
typedef long long ll;
//typedef __int128 i128;
const int N=1e6+5;
const ll inf = 1ll << 60;
//const ll mo=1000000007;
ll m,n;
struct mat{
ll a[3][3];
void init() {
memset(a,0,sizeof(a));
}
friend mat operator * (const mat &a,const mat &b) {
mat c;
c.init();
fo(i,1,2) fo(j,1,2) fo(k,1,2) {
c.a[i][j]+=a.a[i][k]*b.a[k][j]%m;
c.a[i][j]%=m;
}
return c;
}
void print(){
fo(i,1,2) {
fo(j,1,2) printf("%lld ",a[i][j]);
printf("\n");
}
}
};
//ll power(ll a,ll b){
// ll t=1,y=a;
// while (b) {
// if (b&1) t=t*y%m;
// y=y*y%mo;
// b/=2;
// }
// return t;
//}
void solve(ll b){
mat t,y;
t.init();
y.init();
t.a[2][1]=1;
y.a[1][1]=4; y.a[1][2]=2; y.a[2][2]=1;
while (b) {
if (b&1) t=y*t;
y=y*y;
b/=2;
}
ll ans=t.a[1][1];
if (n&1) ans=(ans*2ll+1ll)%m;
printf("%lld\n",ans);
}
int main()
{
// freopen("data.in","r",stdin);
while (scanf("%lld %lld",&n,&m)!=EOF) {
solve(n/2);
}
return 0;
}
标签:hdu,const,int,矩阵,comprehension,4990,ans,include,define
From: https://www.cnblogs.com/ganking/p/17965457