求调,开O2全RE,不开O2能AC
  • 板块P1707 刷题比赛
  • 楼主hhz008
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/1/26 19:37
  • 上次更新2025/1/26 23:56:08
查看原帖
求调,开O2全RE,不开O2能AC
557933
hhz008楼主2025/1/26 19:37

如题,菜菜,大佬们救救

//我服了这题。。。手推矩阵
//nodgd我承认你确实恶心到我了 
#include <iostream>
#include <cstring>

using namespace std;
typedef long long LL;

const int N = 15;

LL n,M;
LL p,q,r,t;
LL u,v,w;
LL x,y,z;

struct matrix	//矩阵 
{
	LL a[N][N];
	LL h,l;	//height, length高度和长度 
	matrix(LL _h, LL _l){
		memset(a,0,sizeof(a));
		h = _h, l = _l;
	}
	//p.s. []不可重载为友元函数 
	LL* operator [](int x) {	//让外部可以直接以形如z[i][j]的方式调用矩阵,而不是z.a[i][j] 
		return a[x];
	}
	friend matrix operator * (matrix a, matrix b); 
	friend matrix operator *= (matrix &a, matrix b){
		a = a*b;
	}
	friend matrix quickpow(matrix a, LL x);
	friend void print(matrix a);
};
LL slowMul(LL a,LL b);	//龟速乘,防止爆long long 

matrix base(11,11);	//11*11的运算矩阵 
matrix ans(1,11);		
//矩阵内分别为{a(k-1), b(k-1), c(k-1), a(k), b(k), c(k), (k-1)^2, k-1, w^(k-1), z^(k-1), 1} 
//	{a(k-1), b(k-1), c(k-1), a(k), b(k), c(k), (k-1)^2, k-1, w^(k-1), z^(k-1), 1}
//	=> {a(k), b(k), c(k), a(k+1), b(k+1), c(k+1), k^2, k, w^k, z^k, 1}
//已知:
//a(k+2)=p*a(k+1)+q*a(k)+b(k+1)+c(k+1)+r*(k^2)+t*k+1, 则 
//a(k+1) = p*a(k) + q*a(k-1) + b(k) + c(k) + r*((k-1)^2) + t*(k-1) + 1 
//同理可知
//b(k+1) = u*b(k) + v*b(k-1) + a(k) + c(k) + w^(k-1) 
//c(k+1) = x*c(k) + y*c(k-1) + a(k) + b(k) + z^(k-1) + k-1 + 2

LL ans1, ans2, ans3;

void __init__();

int main(){
	scanf("%lld%lld",&n,&M);
	scanf("%lld%lld%lld%lld",&p,&q,&r,&t);
	scanf("%lld%lld%lld",&u,&v,&w);
	scanf("%lld%lld%lld",&x,&y,&z);
	__init__();
	if(n == 1){
		ans1 = ans2 = ans3 = 1; 
	}
	else if(n == 2){
		ans1 = ans2 = ans3 = 3;
	}
	else{
		ans = ans*quickpow(base, n-2);
		ans1 = ans[0][3];
		ans2 = ans[0][4];
		ans3 = ans[0][5];
	}
	printf("nodgd %lld\n", ans1);
	printf("Ciocio %lld\n", ans2);
	printf("Nicole %lld\n", ans3);
	
	return 0;
}

void __init__(){	//初始化 
	//矩阵内分别为{a(k-1), b(k-1), c(k-1), a(k), b(k), c(k), (k-1)^2, k-1, w^(k-1), z^(k-1), 1} 
	//芝士矩阵 
	LL o[N][N] = {
		{0, 0, 0, q, 0, 0, 0, 0, 0, 0, 0},	
		{0, 0, 0, 0, v, 0, 0, 0, 0, 0, 0},
		{0, 0, 0, 0, 0, y, 0, 0, 0, 0, 0},
		{1, 0, 0, p, 1, 1, 0, 0, 0, 0, 0},
		{0, 1, 0, 1, u, 1, 0, 0, 0, 0, 0},
		{0, 0, 1, 1, 1, x, 0, 0, 0, 0, 0},
		{0, 0, 0, r, 0, 0, 1, 0, 0, 0, 0},
		{0, 0, 0, t, 0, 1, 2, 1, 0, 0, 0},
		{0, 0, 0, 0, 1, 0, 0, 0, w, 0, 0},
		{0, 0, 0, 0, 0, 1, 0, 0, 0, z, 0},
		{0, 0, 0, 1, 0, 2, 1, 1, 0, 0, 1},
	};
	for(int i = 0;i < 11;i++){
		for(int j = 0;j < 11;j++) base[i][j] = o[i][j]; 
	}
	ans[0][0] = ans[0][1] = ans[0][2] = 1;
	ans[0][3] = ans[0][4] = ans[0][5] = 3;
	ans[0][6] = ans[0][7] = 1;
	ans[0][8] = w;	ans[0][9] = z;	ans[0][10] = 1;
}

LL slowMul(LL a, LL b){
	if(a > b) swap(a,b);
	LL res = 0;
	LL temp = a;
	while(b){
		if(b&1){
			res = (res+temp)%M;
		}
		b >>= 1;
		temp = (temp+temp)%M;
	}
	return res;
}

//重载*运算符,作矩阵乘法 
matrix operator * (matrix a, matrix b){
	//C = A*B => Cij = Aik * Bkj
	matrix res(a.h, b.l);
	if(a.l != b.h) return res; //第一个矩阵的长度必须等于第二个矩阵的宽度
	//设第一个矩阵A长la高ha, 第二个矩阵B长lb高hb, 返回一个ha*lb的矩阵 
	for(int i = 0;i < a.h;i++){
		for(int j = 0;j < b.l;j++){
			for(int k = 0;k < a.l;k++){
				//A矩阵每一行中的k个元素乘上B矩阵每一列中的K个元素 
				res[i][j] += slowMul(a[i][k], b[k][j])%M;
				res[i][j] %= M;
			}
		}
	}
	return res;
}

matrix quickpow(matrix a, LL x){
	if(!x || a.l != a.h) return a;
	matrix temp = a;	//a^1
	//将res初始化为全1,便于乘算 
	matrix res(a.h, a.l);
	for(int i = 0;i < a.h;i++){
		res[i][i] = 1;
	}
	while(x){
		if(x&1){
			res = res * temp;
		}
		x >>= 1;
		temp *= temp;	//a^2, a^4, a^8...
	}
	return res;
}

void print(matrix a){
	for(int i = 0;i < a.h;i++){
		for(int j = 0;j < a.l;j++){
			printf("%d ",a[i][j]);
		}
		puts("");
		}
	return;
}
2025/1/26 19:37
加载中...