[Sdoi2010]古代猪文 (卢卡斯定理,欧拉函数)

哇,这道题真的好好,让我这个菜鸡充分体会到卢卡斯和欧拉函数的强大!

先把题意抽象出来!就是计算这个东西。

p=999911659是素数,p-1=2*3*4679*35617

所以:这样只要求出然后再快速乘法就行了。

那好,怎么做呢?

有模运算的性质得到  然后就是卢卡斯原理。

先把卢卡斯原理放这里:

void init(int mod){                         //对mod取余后,一定小于mod,因此把mod的阶乘存起来就够用
    f[0] = 1;
    for (int i = 1; i <= mod; i++){
        f[i] = f[i - 1] * i % mod;
    }
}

void ex_gcd(LL a, LL b, LL& d, LL& x, LL& y)
{
    if (!b) { d = a; x = 1; y = 0; }
    else{ ex_gcd(b, a%b, d, y, x); y -= x*(a / b); }
}

LL inv(LL a, LL m)
{
    LL d, x, y;
    ex_gcd(a, m, d, x, y);
    return d == 1 ? (x + m) % m : -1;
}

LL Lucas(LL m, LL n, LL p){
    LL  res = 1;
    while (n && m){
        LL n1 = n % p;
        LL m1 = m % p;
        res = res * f[n1] * inv(f[n1 - m1], p) * inv(f[m1], p) % p;
        n /= p;
        m /= p;
    }
    return (res % p + p) % p;
}

则:那么我们其实把它每个存起来Mod[1-4]

然后,就是要找一个值来代替Mod[1-4]。利用中国剩余定理!(哇,太难打了公式了)

什么这样做?因为能同时被2,3,4679,35617那么一定会被99991165同余,那么这个数就是

注意:坑!快速幂一定要加long long,找了3小时的bug

#include<cstdio>
using namespace std;
#define ll long long
const int maxn = 35617;
int N, G, fact[maxn + 5], mod = 999911658;
int prime[5] = { 0, 2, 3, 4679, 35617 }, Mod[5];

void get_fact()

{

    fact[0] = 1;

    for (int i = 1; i <= maxn; i++)

        fact[i] = (ll)fact[i - 1] * i%mod;

}

int ex_t;

void exgcd(int a, int b, int &x, int &y)

{

    if (!b) { x = 1; y = 0; return; }

    exgcd(b, a%b, x, y);

    ex_t = x; x = y; y = ex_t - (a / b)*y;

}

int inv(int a, int p)

{

    int x, y;

    exgcd(a, p, x, y);

    return (x%p + p) % p;

}

int calc(int i, int p)

{

    int ret = 1, x, y, n, m;

    for (x = N, y = i; y; x /= p, y /= p)

    {

        n = x%p; m = y%p;  //卢卡斯定理+预处理阶乘+逆元 

        ret = (ll)ret*fact[n] % p*inv(fact[m], p) % p*inv(n<m ? 0 : fact[n - m], p) % p;

    }

    return ret;

}

ll pow(int x, int n)
{
    int ans = 1;
    for (; n;n>>=1, x=(ll)x*x%mod)
    if (n & 1)ans = (ll)ans*x%mod;
    return ans;
}

int main()
{

    scanf("%d%d", &N, &G);
    if (G % (mod + 1) == 0){ printf("0"); return 0; }
    get_fact();            //得到阶乘
    for (int i = 1; i*i <= N; ++i)        //枚举因子
    {
        if (N%i == 0)
        {
            for (int j = 1; j <= 4; ++j)Mod[j] = (Mod[j] + calc(i, prime[j])) % prime[j];
            if (i*i!=N)
            for (int j = 1; j <= 4; ++j)Mod[j] = (Mod[j] + calc(N / i, prime[j])) % prime[j];
        }
    }
    int x, y, b = 0;
    for (int i = 1; i <= 4; i++)  //中国剩余定理 

    {

        exgcd(mod / prime[i], prime[i], x, y);

        b = (b + (ll)Mod[i] % mod*(mod / prime[i]) % mod*x%mod) % mod;

    }
    b = (b%mod + mod) % mod;    mod += 1;
    //printf("%d\n", b);
    printf("%lld", pow(G, b));
}

原文地址:https://www.cnblogs.com/ALINGMAOMAO/p/9966689.html

时间: 2024-11-09 02:20:10

[Sdoi2010]古代猪文 (卢卡斯定理,欧拉函数)的相关文章

Luogu P2480 [SDOI2010]古代猪文 卢卡斯+组合+CRT

好吧刚开始以为扩展卢卡斯然后就往上套..结果奇奇怪怪又WA又T...后来才意识到它的因子都是质数...qwq怕不是这就是学知识学傻了.. 题意:$ G^{\Sigma_{d|n} \space C_n^d}\space mod \space 999911659$ 首先发现999911659是个质数,所以根据欧拉定理的推论有 $ G^{\Sigma_{d|n}\space C_n^d} \equiv G^{\Sigma_{d|n}\space C_n^d\space mod \space\phi(

1951: [Sdoi2010]古代猪文

1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 2171  Solved: 904[Submit][Status][Discuss] Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时

P2480 [SDOI2010]古代猪文

P2480 [SDOI2010]古代猪文 题目背景 “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔

【poj2154】Color Polya定理+欧拉函数

题目描述 $T$ 组询问,用 $n$ 种颜色去染 $n$ 个点的环,旋转后相同视为同构.求不同构的环的个数模 $p$ 的结果. $T\le 3500,n\le 10^9,p\le 30000$ . 题解 Polya定理+欧拉函数 根据 poj2409 中得到的结论,答案为: $\frac{\sum\limits_{i=1}^nn^{\gcd(i,n)}}n=\sum\limits_{i=1}^nn^{\gcd(i,n)-1}$ 由于 $n$ 有 $10^9$ 之大,因此考虑优化这个式子. 枚举

Polya 定理入门[Burnside引理,Polya定理,欧拉函数]

$这篇blog重点讨论Polya的应用, 更详细的证明请百度 .$ ___ $Burnside引理$ $$L=\frac{1}{|G|}\sum_{i=1}^{|G|}D(a_i)$$ $L$: 本质不同的方案数. $G$: 置换群集合. $a_i$: 置换群中的第 $i$ 个置换. $D(a_i)$: 进行 $a_i$ 这个置换, 状态不会变化的方案 数量. 该引理与下方内容没有太大关系, 可以暂时忽略. ___ $Problem$ 链接 有 $N$ 个石子围成一圈, 使用 $M$ 种颜色染色

费马小定理,欧拉函数

在证明这些定理之前先证明一个有意思的定理. 对于0 mod m,n mod m , 2n mod m, 3n mod m, 4n mod m... (m-1)n mod m 对应解集序列 一定有 m/d份 0 d 2d 3d..m-d. (不一定按照顺序) 这样的解. 其中d = gcd(n,m) 具体点:n=8,m=12.  d = gcd(n,m)=4 对于 0 mod 12,8 mod 12,16 mod 12,24 mod 12,32 mod 12,40 mod 12...88 mod

poj2054Color polya定理+欧拉函数优化

没想到贱贱的数据居然是错的..搞得我调了一中午+晚上一小时(哦不d飞LJH掉RP毕竟他是BUFF)结果重判就对了五次.. 回归正题,这题傻子都看得出是polya定理(如果你不是傻子就看这里),还没有翻转,就一个旋转,结果我就欢快的打完交上去了.傻子都知道会TLE,n<=1e9啊,O(n)都原地爆炸,那怎么办...一脸懵逼(然后就膜题解了) 可以发现,这题公式就是sigma(gcd(k,n))(k=1~n),然后该怎么优化呢,我(??)发现gcd(k,n)里面肯定有一些k和n的gcd是相同的,那我

【SPOJ419】Transposing is Fun P&#243;lya定理+欧拉函数

[SPOJ419]Transposing is Fun 题意:给你一个$2^a\times2^b$的矩阵,将$1...n$中的数依次从左到右,从上往下填到矩阵里,再把矩阵转置,然后把所有数从左到右,从上往下拿出来得到一个新的排列$A$.你现在每次可以交换两个数,问你从$1...n$变成排列$A$最少要进行多少次操作. 询问次数$\le400000,a+b\le 10^6$ 题解:首先我们可以找到所有的循环节,如果一个循环节中有$x$个数,需要交换$x-1$次.所以我们只需要求出循环节的个数$k$

【BZOJ1951】【SDOI2010】古代猪文 Lucas定理、中国剩余定理、exgcd、费马小定理

Description “在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国.猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了.因此也很少有其他动物知道这样一个王国. 猪王国虽然不大,但是土地肥沃,屋舍俨然.如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃花源了.猪