您的位置:首页 > 其它

洛谷P1707 刷题比赛

2018-03-04 18:37 363 查看

题目背景

nodgd是一个喜欢写程序的同学,前不久洛谷OJ横空出世,nodgd同学当然第一时间来到洛谷OJ刷题。于是发生了一系列有趣的事情,他就打算用这些事情来出题恶心大家……

题目描述

洛谷OJ当然算是好地方,nodgd同学打算和朋友分享一下。于是他就拉上了他的朋友Ciocio和Nicole两位同学一起刷题。喜欢比赛的他们当然不放过这样一次刷题比赛的机会!在第1天nodgd,Coicoi,Nicole都只做了1道题。在第2天nodgd,Coicoi,Nicole都只做了3道题。他们都有着严格的刷题规则,并且会在每一天都很遵守规则的刷一定量的题。(1)nodgd同学第k+2天刷题数量a[k+2]=p*a[k+1]+q*a[k]+b[k+1]+c[k+1]+r*k^2+t*k+1;(2)Ciocio同学第k+2天刷题数量b[k+2]=u*b[k+1]+v*b[k]+a[k+1]+c[k+1]+w^k;(3)Nicole同学第k+2天刷题数量c[k+2]=x*c[k+1]+y*c[k]+a[k+1]+b[k+1]+z^k+k+2;(以上的字母p,q,r,t,u,v,w,x,y,z都是给定的常数,并保证是正整数)于是他们开始了长时间的刷题比赛!一共进行了N天(4<=N<=10^16)但是时间是可贵的,nodgd想快速知道第N天每个人的刷题数量。不过nodgd同学还有大量的数学竞赛题、物理竞赛题、英语竞赛题、美术竞赛题、体育竞赛题……要做,就拜托你来帮他算算了。由于结果很大,输出结果mod K的值即可。

输入输出格式

输入格式:第一行两个正整数N,K。(4<=N<=10^16,2<=K<=10^16)第二行四个正整数p,q,r,t。第三行三个正整数u,v,w。第四行三个正整数x,y,z。(保证p,q,r,t,u,v,w,x,y,z都是不超过100的正整数)
输出格式:共三行,每行一个名字+一个空格+一个整数。依次是nodgd,Ciocio,Nicole和他们在第N天刷题数量mod K的值。

输入输出样例

输入样例#1: 
4 10007
2 1 1 1
2 2 3
1 1 2
输出样例#1: 
nodgd 74
Ciocio 80
Nicole 59

说明

矩阵乘法。注意,中间相乘过程可能会比64位长整型的数据范围还要大。矩阵快速幂。。。矩阵如下(造了我10min+):【 0 q 0 0 0 0 0 0 0 0 0 】【 1 p 0 1 0 1 0 0 0 0 0 】【 0 0 0 u 0 0 0 0 0 0 0 】【 0 1 1 v 0 1 0 0 0 0 0 】【 0 0 0 0 0 x 0 0 0 0 0 】【 0 1 0 1 1 y 0 0 0 0 0 】【 0 r 0 0 0 0 1 0 0 0 0 】【 0 t 0 0 0 1 2 1 0 0 0 】【 0 0 0 1 0 0 0 0 w 0 0 】【 0 0 0 0 0 1 0 0 0 z 0 】【 0 1 0 0 0 2 1 1 0 0 1 】剩下的基本是板子。。。
附代码:#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 15
using namespace std;
unsigned long long n,mod;
struct node{
unsigned long long a[MAXN][MAXN];
}base,ans;
inline long long read(){
long long date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
unsigned long long mul(unsigned long long x,unsigned long long y){
unsigned long long s=0;
while(y){
if(y&1)s=(s+x)%mod;
x=(x<<1)%mod;
y>>=1;
}
return s%mod;
}
node operator *(const node &x,const node &y){
node ret;
for(int i=1;i<=11;i++)
for(int j=1;j<=11;j++){
ret.a[i][j]=0;
for(int k=1;k<=11;k++){
ret.a[i][j]+=mul((x.a[i][k]%mod),(y.a[k][j]%mod))%mod;
ret.a[i][j]%=mod;
}
}
return ret;
}
void mexp(long long k){
while(k){
if(k&1)ans=ans*base;
base=base*base;
k>>=1;
}
}
int main(){
n=read()-2;mod=read();
memset(base.a,0,sizeof(base.a));
base.a[1][1]=base.a[1][2]=base.a[1][3]=base.a[1][9]=base.a[2][2]=base.a[2][11]=base.a[3][3]=base.a[4][11]=base.a[5][10]=1;
base.a[9][6]=base.a[9][10]=base.a[9][11]=base.a[10][7]=base.a[10][9]=base.a[10][11]=base.a[11][8]=base.a[11][9]=base.a[11][10]=1;
base.a[1][11]=base.a[2][3]=2;
base.a[9][9]=read();base.a[6][9]=read();base.a[3][9]=read();base.a[2][9]=read();
base.a[10][10]=read();base.a[7][10]=read();base.a[5][5]=read();
base.a[11][11]=read();base.a[8][11]=read();base.a[4][4]=read();
ans.a[1][1]=ans.a[1][2]=ans.a[1][3]=ans.a[1][6]=ans.a[1][7]=ans.a[1][8]=1;
ans.a[1][4]=base.a[4][4];ans.a[1][5]=base.a[5][5];ans.a[1][9]=ans.a[1][10]=ans.a[1][11]=3;
mexp(n);
printf("nodgd %lld\nCiocio %lld\nNicole %lld\n",ans.a[1][9]%mod,ans.a[1][10]%mod,ans.a[1][11]%mod);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: