zoukankan      html  css  js  c++  java
  • [题解] [SDOI2010] 古代猪文

    题面

    题解

    题目所求即为

    [G ^ {sum_{d | n}C_{n}^{d}} mod {999911659} ]

    考虑到有这样一个式子

    [a ^ b equiv a ^ {b mod varphi(p)} pmod p ]

    由于999911659是一个质数, 所以(varphi(999911659) = 999911658), 所以原式就变为了

    [G^{sum_{d | n} C_n^d mod 999911568} mod 999911659 ]

    左边的东西只要求出(sum_{d | n} C_n^d mod 999911568)即可快速幂, 所以题目转化为求左式

    我们发现(999911568 = 2 * 3 * 4257 * 35617), 恩, 组合数取模求和, 上(exLucas)板子即可

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <vector>
    #define itn int
    #define reaD read
    #define Mod 999911659
    #define int long long
    using namespace std;
    
    int n, m, mod[4] = { 2, 3, 4679, 35617 }, inv[4][50005], jc[4][50005], r[4]; 
    
    inline int read()
    {
    	int x = 0, w = 1; char c = getchar();
    	while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
    	while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    	return x * w;
    }
    
    int fpow(int x, int y)
    {
    	int res = 1;
    	while(y)
    	{
    		if(y & 1) res = res * x % Mod;
    		x = x * x % Mod;
    		y >>= 1; 
    	}
    	return res; 
    }
    
    int exgcd(int a, int b, int &x, itn &y)
    {
    	if(!b) { x = 1; y = 0; return a; }
    	int q = a / b, r = a % b, d = exgcd(b, r, y, x);
    	y -= q * x; return d; 
    }
    
    itn C(int n, int m, int opt)
    {
    	if(m > n) return 0; if(m > n - m) m = n - m; 
    	return 1ll * jc[opt][n] * inv[opt][m] % mod[opt] * inv[opt][(n - m)] % mod[opt]; 
    }
    
    int lucas(int n, int m, int opt)
    {
    	if(!m) return 1; 
    	return 1ll * C(n % mod[opt], m % mod[opt], opt) * lucas(n / mod[opt], m / mod[opt], opt) % mod[opt]; 
    }
    
    int excrt()
    {
    	int p1 = mod[0], r1 = r[0]; 
    	for(int j = 1; j < 4; j++)
    	{
    		int p2 = mod[j], r2 = r[j], x, y, d = exgcd(p1, p2, x, y); 
    		x *= (r2 - r1) / d; p2 /= d; x = (x % p2 + p2) % p2;
    		r1 = p1 * x + r1; p1 = p1 * p2; 
    	}
    	return r1; 
    }
    
    int exlucas()
    {
    	for(int i = 1; i * i <= n; i++)
    		if(n % i == 0)
    		{
    			if(i * i == n) for(int j = 0; j < 4; j++) r[j] = 1ll * (r[j] + lucas(n, i, j)) % mod[j];
    			else for(int j = 0; j < 4; j++) r[j] = 1ll * (r[j] + lucas(n, i, j) + lucas(n, n / i, j)) % mod[j]; 
    		}
    	return excrt(); 
    }
    
    signed main()
    {
    	n = read(); m = read();
    	if(m % 999911659 == 0) { puts("0"); return 0; }
    	for(int i = 0; i <= 3; i++)
    	{
    		inv[i][0] = inv[i][1] = 1; jc[i][0] = jc[i][1] = 1; 
    		for(int j = 2; j < mod[i]; j++) inv[i][j] = 1ll * (mod[i] - mod[i] / j) * inv[i][mod[i] % j] % mod[i];
    		for(int j = 2; j < mod[i]; j++) inv[i][j] = 1ll * inv[i][j - 1] * inv[i][j] % mod[i]; 
    		for(int j = 2; j < mod[i]; j++) jc[i][j] = 1ll * jc[i][j - 1] * j % mod[i]; 
    	}
    	printf("%lld
    ", fpow(m, exlucas())); 
    	return 0;
    }
    
  • 相关阅读:
    python wsdl connection refused 111
    我要学算法
    linux 定时任务
    mysql语句
    Firefox配置Fiddler
    windows下安装spynner
    做一个完整的项目需要技能
    快速排序
    《实时控制软件设计》总结
    asp实现在微信jsdk分享从a页面跳转到b页面然后分享后点开又回a页面
  • 原文地址:https://www.cnblogs.com/ztlztl/p/11087137.html
Copyright © 2011-2022 走看看