码迷,mamicode.com
首页 > 其他好文 > 详细

题解[LuoguP1707 刷题比赛]

时间:2021-03-06 14:41:33      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:splay   names   刷题   struct   ioc   简单   main   int   har   

题目描述

Link

给定\(n,P,p,q,r,t,u,v,w,x,y,z\) ,三个递推式:

\[a_{k+2}=pa_{k+1}+qa_{k}+b_{k+1}+c_{k+1}+rk^2+tk+1 \]

\[b_{k+2}=ub_{k+1}+vb_{k}+a_{k+1}+c_{k+1}+w^k \]

\[c_{k+2}=xc_{k+1}+yc_{k}+a_{k+1}+b_{k+1}+z^k+k+2 \]

\(a_n , b_n ,c_n(\%P)\)

Sol

一定先静下心来,把题目看好了。

变量名什么的尽量跟题目一样,耐心推矩阵。

最好还是和题目一样设式子,因为观察发现题目给的式子最简单,没有什么\((k+1)^2,(k-1)^2\)之类要拆的式子。

递推\(11\)个量:

\[a_{k+1},b_{k+1},c_{k+1},a_k,b_k,c_k,k,k^2,w^k,z^k,1 \]

小技巧:凡是随着\(k\)的变化而变化的值都应放入初始矩阵中,转移矩阵只放常量。每一个矩乘都可以往这上面靠。

推出\(11×11\)的矩阵就直接套模板,可以啦(≧▽≦)/

初始矩阵:

3 0 0 0 0 0 0 0 0 0 0 
3 0 0 0 0 0 0 0 0 0 0 
3 0 0 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 0 0 
k 0 0 0 0 0 0 0 0 0 0 
1 0 0 0 0 0 0 0 0 0 0 
w 0 0 0 0 0 0 0 0 0 0 
z 0 0 0 0 0 0 0 0 0 0 
k^2 0 0 0 0 0 0 0 0 0 0 

转移矩阵:

p 1 1 q 0 0 t 1 0 0 r
1 u 1 0 v 0 0 0 1 0 0
1 1 x 0 0 y 1 2 0 1 0 
1 0 0 0 0 0 0 0 0 0 0 
0 1 0 0 0 0 0 0 0 0 0 
0 0 1 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 1 1 0 0 0 
0 0 0 0 0 0 0 1 0 0 0 
0 0 0 0 0 0 0 0 w 0 0 
0 0 0 0 0 0 0 0 0 z 0 
0 0 0 0 0 0 2 1 0 0 1

别忘了龟速乘。

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct xbk{
	ll m[12][12];
}a,st,flag,f0;
ll n,P,p,q,r,t,u,v,w,x,y,z;
inline ll read(){
	ll w=0;
	char ch=getchar();
	while(ch>‘9‘||ch<‘0‘) ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘){
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w;
}
inline ll mul1(ll a,ll b){
	ll res=0;
	while(b){
		if(b&1) res=(res+a)%P;
		a=(a+a)%P;
		b>>=1;
	}
	return res;
}
xbk mul(xbk aa,xbk bb){
	xbk c=f0;
	for(int i=1;i<=11;i++){
		for(int j=1;j<=11;j++){
			for(int k=1;k<=11;k++){
				c.m[i][j]=(c.m[i][j]+mul1(bb.m[i][k],aa.m[k][j])%P)%P;
			}
		}
	}
	return c;
}
xbk ksm(xbk aa,ll b){
	xbk res=flag;
	while(b){
		if(b&1) res=mul(res,aa);
		aa=mul(aa,aa);
		b>>=1;
	}
	return res;
}
int main(){
	n=read(),P=read();
	p=read(),q=read(),r=read(),t=read();
	u=read(),v=read(),w=read();
	x=read(),y=read(),z=read();
	for(int i=1;i<=11;i++){
		for(int j=1;j<=11;j++){
			flag.m[j][j]=1,a.m[i][j]=0,f0.m[i][j]=0;
		}		
	}
	a.m[1][1]=p,a.m[1][2]=1,a.m[1][3]=1,a.m[1][4]=q,a.m[1][7]=t,a.m[1][8]=1,a.m[1][11]=r;
	a.m[2][1]=1,a.m[2][2]=u,a.m[2][3]=1,a.m[2][5]=v,a.m[2][9]=1;
	a.m[3][1]=1,a.m[3][2]=1,a.m[3][3]=x,a.m[3][6]=y,a.m[3][7]=1,a.m[3][8]=2,a.m[3][10]=1;
	a.m[4][1]=1,a.m[5][2]=1,a.m[6][3]=1;
	a.m[7][7]=1,a.m[7][8]=1;
	a.m[8][8]=1;
	a.m[9][9]=w;
	a.m[10][10]=z;
	a.m[11][7]=2,a.m[11][8]=1,a.m[11][11]=1;
	st.m[1][1]=3,st.m[2][1]=3,st.m[3][1]=3;
	st.m[4][1]=1,st.m[5][1]=1,st.m[6][1]=1;
	st.m[7][1]=1,st.m[8][1]=1,st.m[9][1]=w;
	st.m[10][1]=z,st.m[11][1]=1;
	xbk ans=ksm(a,n-2);
	ans=mul(st,ans);
	printf("nodgd %lld\nCiocio %lld\nNicole %lld\n",ans.m[1][1],ans.m[2][1],ans.m[3][1]);
	return 0;
}

完结撒花?

题解[LuoguP1707 刷题比赛]

标签:splay   names   刷题   struct   ioc   简单   main   int   har   

原文地址:https://www.cnblogs.com/xxbbkk/p/14488368.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!