您的位置:首页 > 其它

1951: [Sdoi2010]古代猪文

2016-11-06 19:08 183 查看

1951: [Sdoi2010]古代猪文

Time Limit: 1 Sec  Memory Limit: 64 MB
Submit: 2036  Solved: 843

[Submit][Status][Discuss]

Description

“在那山的那边海的那边有一群小肥猪。他们活泼又聪明,他们调皮又灵敏。他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心……” ——选自猪王国民歌 很久很久以前,在山的那边海的那边的某片风水宝地曾经存在过一个猪王国。猪王国地理位置偏僻,实施的是适应当时社会的自给自足的庄园经济,很少与外界联系,商贸活动就更少了。因此也很少有其他动物知道这样一个王国。 猪王国虽然不大,但是土地肥沃,屋舍俨然。如果一定要拿什么与之相比的话,那就只能是东晋陶渊明笔下的大家想象中的桃花源了。猪王勤政爱民,猪民安居乐业,邻里和睦相处,国家秩序井然,经济欣欣向荣,社会和谐稳定。和谐的社会带给猪民们对工作火红的热情和对未来的粉色的憧憬。
小猪iPig是猪王国的一个很普通的公民。小猪今年10岁了,在大肥猪学校上小学三年级。和大多数猪一样,他不是很聪明,因此经常遇到很多或者稀奇古怪或者旁人看来轻而易举的事情令他大伤脑筋。小猪后来参加了全猪信息学奥林匹克竞赛(Pig Olympiad in Informatics, POI),取得了不错的名次,最终保送进入了猪王国大学(Pig Kingdom University, PKU)深造。 现在的小猪已经能用计算机解决简单的问题了,比如能用P++语言编写程序计算出A + B的值。这个“成就”已经成为了他津津乐道的话题。当然,不明真相的同学们也开始对他刮目相看啦~
小猪的故事就将从此展开,伴随大家两天时间,希望大家能够喜欢小猪。 题目描述 猪王国的文明源远流长,博大精深。 iPig在大肥猪学校图书馆中查阅资料,得知远古时期猪文文字总个数为N。当然,一种语言如果字数很多,字典也相应会很大。当时的猪王国国王考虑到如果修一本字典,规模有可能远远超过康熙字典,花费的猪力、物力将难以估量。故考虑再三没有进行这一项劳猪伤财之举。当然,猪王国的文字后来随着历史变迁逐渐进行了简化,去掉了一些不常用的字。 iPig打算研究古时某个朝代的猪文文字。根据相关文献记载,那个朝代流传的猪文文字恰好为远古时期的k分之一,其中k是N的一个正约数(可以是1和N)。不过具体是哪k分之一,以及k是多少,由于历史过于久远,已经无从考证了。
iPig觉得只要符合文献,每一种能整除N的k都是有可能的。他打算考虑到所有可能的k。显然当k等于某个定值时,该朝的猪文文字个数为N / k。然而从N个文字中保留下N / k个的情况也是相当多的。iPig预计,如果所有可能的k的所有情况数加起来为P的话,那么他研究古代文字的代价将会是G的P次方。 现在他想知道猪王国研究古代文字的代价是多少。由于iPig觉得这个数字可能是天文数字,所以你只需要告诉他答案除以999911659的余数就可以了。

Input

有且仅有一行:两个数N、G,用一个空格分开。

Output

有且仅有一行:一个数,表示答案除以999911659的余数。

Sample Input

4 2

Sample Output

2048

HINT

10%的数据中,1 <= N <= 50;

20%的数据中,1 <= N <= 1000;

40%的数据中,1 <= N <= 100000;

100%的数据中,1 <= G <= 1000000000,1 <= N <= 1000000000。

Source

Sdoi2010 Contest2

[Submit][Status][Discuss]

这非常的数学。。综合了好多个定理--
首先原题可以简化为求G^∑C(N,i) % p  (i|N)
i的话,根号级别枚举即可
p = 999911659,这显然是个大素数
然后这个幂次非常大,但是根据欧拉定理,x^k ≡ x^(k%phi(p)) (mod p)
phi(p)为欧拉函数,,这里p = [b]999911659,所以phi(p) = [b]999911658[/b][/b]
[b][b]如果是大组合数模一个素数,可以用Lucas定理解决[/b][/b]
[b][b]但是,phi(p)是个合数,大组合数%一个合数。。?[/b][/b]
[b][b]分解质因子
phi(p) = 2*3*4679*35617
[/b][/b]
[b][b]发现质因子个数非常少,而且都只有1次[/b][/b]
[b][b]首先可以用这四个素数分别求一次当前要求的组合数[/b][/b]
[b][b]因为是素数了,所以Lucas定理log就解决[/b][/b]
[b][b]剩下就是四个xi
≡ bi (mod mi)的形式,其中mi互质,这时候再用个中国剩余定理就行
[/b][/b]
[b][b]一开始O(n)推出四个模数下的所有阶乘和逆元,,这样后面就很好写了[/b][/b]
[b][/b]
[b][/b]
[b][b]啊。。苟蒻忘光了中国剩余定理。。这里记点东西,,[/b][/b]
[b][b]记M
= πmi ,,xi = Mi^-1*Mi,Mi = M/mi,Mi^-1是Mi在%mi下的逆元
[/b][/b]
[b][b]那么x
= ∑xi*bi % M
[/b][/b]
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

const int pri[4] = {2,3,4679,35617};
const int mo = 999911659;

int N,G,ans = 1,fac[4][40000],inv[4][40000];

int Mul(int x,int y,int z) {return 1LL*x*y%z;}
int Add(int x,int y,int z) {return (1LL*x+1LL*y)%z;}

int ksm(int x,int y,int z)
{
int ret = 1;
for (; y; y >>= 1) {
if (y&1) ret = Mul(ret,x,z);
x = Mul(x,x,z);
}
return ret;
}

int C(int n,int m,int o)
{
int t = Mul(inv[o][m],inv[o][n-m],pri[o]);
return Mul(fac[o]
,t,pri[o]);
}

int Lucas(int n,int m,int p,int o)
{
if (!m) return 1;
return Mul(Lucas(n/p,m/p,p,o),C(n%p,m%p,o),p);
}

int Cal(int k)
{
int ret = 0;
for (int i = 0; i < 4; i++) {
int M = (mo-1)/pri[i];
int inv = ksm(M,pri[i]-2,pri[i]);
M = Mul(M,inv,mo-1);
int B = Lucas(N,k,pri[i],i);
ret = Add(ret,Mul(B,M,mo-1),mo-1);
}
return ret;
}

int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif

for (int i = 0; i < 4; i++) {
fac[i][0] = 1;
for (int j = 1; j < pri[i]; j++) fac[i][j] = Mul(fac[i][j-1],j,pri[i]);
inv[i][pri[i]-1] = ksm(fac[i][pri[i]-1],pri[i]-2,pri[i]);
for (int j = pri[i]-2; j >= 0; j--) inv[i][j] = Mul(inv[i][j+1],j+1,pri[i]);
}
cin >> N >> G; int Sqrt = sqrt(N);
if (G == mo) {cout << 0; return 0;}
for (int i = 1; i <= Sqrt; i++)
if (N % i == 0) {
ans = Mul(ans,ksm(G,Cal(i),mo),mo);
if (N / i != i) ans = Mul(ans,ksm(G,Cal(N/i),mo),mo);
}
cout << ans;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: