zoukankan      html  css  js  c++  java
  • bzoj 3328: PYXFIB

    题目传送门:bzoj 3328

    题意简述:

    题目说的很清楚了。

    题解:

    首先注意到:

    [mathrm{Ans}=sum_{i}inom{n}{i}F_{i}[k|i] ]

    考虑矩阵 (mathbf{A}=egin{bmatrix}1&1\1&0end{bmatrix}),则 (F_i=left[A^i ight]_{1,1})

    所以有:

    [mathrm{Ans}=left[sum_{i}inom{n}{i}mathbf{A}^i[k|i] ight]_{1,1} ]

    考虑形如 ([k|i]) 的式子使用单位根反演化简,有:

    [egin{aligned}mathrm{Ans}&=left[sum_{i}inom{n}{i}mathbf{A}^ifrac{1}{k}sum_{j=0}^{k-1}left(omega_{k}^{j} ight)^{i} ight]_{1,1}\&=frac{1}{k}left[sum_{j=0}^{k-1}sum_{i}inom{n}{i}left(omega_{k}^{j}mathbf{A} ight)^{i} ight]_{1,1}end{aligned} ]

    用二项式定理化简,其中 (mathbf{I}) 是单位矩阵 (egin{bmatrix}1&0\0&1end{bmatrix})

    [egin{aligned}mathrm{Ans}&=frac{1}{k}left[sum_{j=0}^{k-1}sum_{i}inom{n}{i}left(omega_{k}^{j}mathbf{A} ight)^{i} ight]_{1,1}\&=frac{1}{k}left[sum_{j=0}^{k-1}left(mathbf{I}+omega_{k}^{j}mathbf{A} ight)^n ight]_{1,1}end{aligned} ]

    最后,考虑可行性,因为 (pequiv 1pmod{k}),即 (k)(varphi(p)) 的因数,求出 (p) 的原根 (g) 之后,则 (g^{frac{varphi(p)}{k}}) 即可当作模意义下的 (omega_{k})

    代码如下:

    #include <cstdio>
    
    typedef long long LL;
    
    LL N;
    int K, P, G;
    
    inline int qPow(int b, LL e) {
    	int a = 1;
    	for (; e; e >>= 1, b = (LL)b * b % P)
    		if (e & 1) a = (LL)a * b % P;
    	return a;
    }
    
    inline void getG() {
    	int X = P - 1, Y = X, t = 0;
    	static int p[10];
    	for (int i = 2; i * i <= Y; ++i) {
    		if (Y % i) continue;
    		p[++t] = i;
    		while (Y % i == 0) Y /= i;
    	} if (Y > 1) p[++t] = Y;
    	for (int g = 2; ; ++g) {
    		int ok = 1;
    		for (int i = 1; i <= t; ++i)
    			if (qPow(g, X / p[i]) == 1) { ok = 0; break; }
    		if (ok) { G = qPow(g, X / K); break ; }
    	}
    }
    
    struct Mat {
    	int A11, A12, A21, A22;
    	Mat() {}
    	Mat(int A11, int A12, int A21, int A22) :
    		A11(A11), A12(A12), A21(A21), A22(A22) {}
    	inline friend Mat operator +(Mat A, Mat B) {
    		return Mat((A.A11 + B.A11) % P, (A.A12 + B.A12) % P, (A.A21 + B.A21) % P, (A.A22 + B.A22) % P);
    	}
    	inline friend Mat operator *(Mat A, Mat B) {
    		return Mat(
    			((LL)A.A11 * B.A11 + (LL)A.A12 * B.A21) % P,
    			((LL)A.A11 * B.A12 + (LL)A.A12 * B.A22) % P,
    			((LL)A.A21 * B.A11 + (LL)A.A22 * B.A21) % P,
    			((LL)A.A21 * B.A12 + (LL)A.A22 * B.A22) % P
    		);
    	}
    	inline friend Mat operator ^(Mat B, LL E) {
    		Mat A(1, 0, 0, 1);
    		for (; E; E >>= 1, B = B * B)
    			if (E & 1) A = A * B;
    		return A;
    	}
    };
    
    int main() {
    	int T; scanf("%d", &T);
    	while (T--) {
    		scanf("%lld%d%d", &N, &K, &P);
    		getG();
    		Mat I(1, 0, 0, 1), W(G, 0, 0, G), A(1, 1, 1, 0), Ans(0, 0, 0, 0);
    		for (int j = 0; j < K; ++j) {
    			Ans = Ans + ((I + A) ^ N);
    			A = A * W;
    		}
    		printf("%lld
    ", (LL)Ans.A11 * qPow(K, P - 2) % P);
    	}
    	return 0;
    }
    
  • 相关阅读:
    去除Html标签
    asp.net弹出多个模态窗口
    window.returnValue的用法
    eTerm-用于报价的指令(GK状态码的使用)
    使用ffmpeg 操作音频文件前后部分静音移除.
    使用Visual Studio 2017开发python,并在iis上部署Python Django
    解决wampserver 服务无法启动
    网站优化记录-通过命令预编译Asp.net 网站,成功优化到毫秒级别。
    Scut游戏引擎改造兼容Codis。
    windows修改Host后未生效。
  • 原文地址:https://www.cnblogs.com/PinkRabbit/p/11044731.html
Copyright © 2011-2022 走看看