P1951: [Sdoi2010]古代猪文
呜啊啊啊啊,选错了题,原以为很简单的优化+剪枝就能过结果牵扯到了一堆数论知识。我的错,贴上我的代码(已经尽量优化了)
const maxn=;
var n,g,i,j,ans:longint;
tem:int64;
function pow(g,x:longint):longint;
var
now,tem,i,t:int64;
begin
tem:=; now:=g;
if g= then exit();
while now<maxn do
begin
now:=now*now;
tem:=tem*;
end;
now:=now mod maxn;
if (now=) and (x div tem>=) then exit();
if x div tem>= then t:=pow(now,x div tem)
else t:=;
now:=g; x:=x-tem*(x div tem);
while x<> do
begin
if (x mod )= then begin
t:=(t*now) mod maxn;
end;
now:=(now*now) mod maxn;
x:=x div ;
end;
exit(t mod maxn);
end;
function c(x:longint):longint;
var i:longint;
tem:int64;
begin
tem:=g;
for i:= to x do
tem:=pow(tem,n-i+) mod maxn;
for i:= to x do tem:=trunc(exp(ln(tem)/i));
exit(tem);
end;
begin
readln(n,g);
tem:=;
for i:= to trunc(sqrt(n)) do
if n mod i= then
begin
if i*i<>n then tem:=tem*((c(i) mod maxn)*(c(n div i) mod maxn) mod maxn) mod maxn
else tem:=(tem*c(i)) mod maxn;
end;
writeln(tem mod maxn);
end.
然而正确的是。。
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdio>
using namespace std;
#define maxn 35620
typedef long long LL;
#define MOD 999911659
#define M 999911658
LL w[]={,,,};
LL a[];
LL fac[][maxn];
LL Pow(LL a,LL b,LL mod)//快速幂
{
LL ans=;
while(b)
{
if(b&) ans=(ans*a)%mod;
a=(a*a)%mod;
b >>= ;
}
return ans;
}
void init()//预处理阶乘
{
for(int i=;i<;i++)
{
fac[i][]=;
for(int j=;j<=w[i];j++)
{
fac[i][j]=(fac[i][j-]*j)%w[i];
}
}
}
/********************************
* 组合数取模用费马小定理
*********************************/
LL C(LL n,LL m,int x)//组合数取模
{
if(n < m) return ;
return (fac[x][n] * Pow((fac[x][n-m]*fac[x][m]),w[x]-,w[x]))%w[x];
}
/*******************************
* lucas 处理大组合数取模
********************************/
LL Lucas(LL n,LL m,int x)//lucas定理
{
if(m==) return ;
return (Lucas(n/w[x],m/w[x],x)*C(n%w[x],m%w[x],x))%w[x];
}
/****************************
* 扩展欧几里得求乘法逆元
*****************************/
LL exgcd(LL a,LL b,LL &x,LL &y)//乘法逆元
{
if(!b){x = ;y = ;return a;} LL ans = exgcd(b,a%b,x,y); LL t = x;x = y;y = t - a/b*y; return ans;
}
/***************************************************************************************
* 中国剩余定理:
* x = b1 % m1
* x = b2 % m2
* x = b3 % m3
* .
* gcd(m1,m2,m3,...) = 1;
* M = m1 * m2 * m3 *.....;
* M1 = m2 * m3 * ...., M2 = m1 * m3 * ...., M3 = m1 * m2 * m4 *....., ......;
* M1 * M(-1) = 1 % M ,M2 * M2(-1) = 1 % M;
* res = (M1(-1)*b1 + M2(-1)*b2+.....)%M;res即为所求值
* 注:如果取模的值相同:都是m1 那么 bn的值可以相加计算;
* 略屌。。。。。。。。。。。。。。
*
*****************************************************************************************/
LL CRT()//计算组合数和取模之后的值
{
LL i,d,x0,y0,ans=;
for(i = ;i < ;i++)//中国剩余定理
{
d=M/w[i];
exgcd(d,w[i],x0,y0);
ans=(ans+d*x0*a[i])%M;
}
if(ans <= ) ans += M;
return ans;
}
int main()
{
init();
LL g,n;
while(cin>>n>>g)
{
memset(a,,sizeof(a));
for(int i=;i*i<=n;i++)
{
if(n%i==)
{
LL tmp=n/i;
for(int j=;j<;j++)
{
if(tmp!=i) a[j]=(a[j]+Lucas(n,i,j))%w[j];
a[j]=(a[j]+Lucas(n,tmp,j))%w[j];
}
}
}
cout<<Pow(g%MOD,CRT(),MOD)<<endl;
}
return ;
}
我就不想多说了=-=
(转载请注明出处:http://www.cnblogs.com/Kalenda/)
P1951: [Sdoi2010]古代猪文的更多相关文章
- BZOJ 1951: [Sdoi2010]古代猪文( 数论 )
显然答案是G^∑C(d,N)(d|N).O(N^0.5)枚举N的约数.取模的数999911659是质数, 考虑欧拉定理a^phi(p)=1(mod p)(a与p互质), 那么a^t mod p = a ...
- 1951: [Sdoi2010]古代猪文
1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2171 Solved: 904[Submit][Status] ...
- BZOJ 1951: [Sdoi2010]古代猪文 [Lucas定理 中国剩余定理]
1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2194 Solved: 919[Submit][Status] ...
- [SDOI2010]古代猪文 (欧拉,卢卡斯,中国剩余)
[SDOI2010]古代猪文 \(solution:\) 这道题感觉综合性极强,用到了许多数论中的知识: 质因子,约数,组合数 欧拉定理 卢卡斯定理 中国剩余定理 首先我们读题,发现题目需要我们枚举k ...
- 洛咕 P2480 [SDOI2010]古代猪文
洛咕 P2480 [SDOI2010]古代猪文 题目是要求\(G^{\sum_{d|n}C^d_n}\). 用费马小定理\(G^{\sum_{d|n}C^d_n\text{mod 999911658} ...
- 【BZOJ1951】[SDOI2010]古代猪文
[BZOJ1951][SDOI2010]古代猪文 题面 bzoj 洛谷 题解 题目实际上是要求 $ G^{\sum d|n\;C_n^d}\;mod \; 999911659 $ 而这个奇怪的模数实际 ...
- 【BZOJ1951】[Sdoi2010]古代猪文 Lucas定理+CRT
[BZOJ1951][Sdoi2010]古代猪文 Description 求$X=\sum\limits_{d|n}C_n^d$,$Ans=G^X (\mod 999911659)$. Input 有 ...
- 洛谷 P2480 [SDOI2010]古代猪文 解题报告
P2480 [SDOI2010]古代猪文 题目背景 "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" ...
- 【bzoj1951】: [Sdoi2010]古代猪文 数论-中国剩余定理-Lucas定理
[bzoj1951]: [Sdoi2010]古代猪文 因为999911659是个素数 欧拉定理得 然后指数上中国剩余定理 然后分别lucas定理就好了 注意G==P的时候的特判 /* http://w ...
随机推荐
- Vim中的正则表达式[转]
来自:http://blog.csdn.net/endall/archive/2007/08/29/1764554.aspx Vim中的正则表达式功能很强大,如果能自由运用,则可以完成很多难以想象的操 ...
- su:认证失败
使用命令[su - root]切换用户,提示[su:认证失败] 原因:Ubuntu安装之后,root用户默认是被锁定的,不允许登录,也不允许su到root. 解决:重新设置密码 在终端输入命令:sud ...
- 【EF学习笔记04】----------EF简单增删改查
第一步:创建上下文对象 using(var db = new Entities()) { //数据操作 } 新增 UserInfo user = new UserInfo() { UserName = ...
- .NET中的字符串你了解多少?
字符串的特性 1.不可变性 由于字符串是不可变的的,每次修改字符串,都是创建了一个单独字符串副本(拷贝了一个字符串副本).之所以发生改变只是因为指向了一块新的地址. ps: ...
- 简单linux网络驱动程序
本文代码参考<LINUX设备驱动程序>第十七章 网络驱动程序 网络地址和虚拟主机地址为: snullnet0 192.168.0.0 snullnet1 192.168.1.0 local ...
- Linux manual中命令标号的含义
如果查看Linux manual(例如,执行:man open), 会发现文档中有这样的表达方式:read(2), write(2), lseek(2), fcntl(2)等,括号中的数值表达什么含义 ...
- C++ 里 构建动态二维数组
//****动态二维数组 /* int m=3; int **data; int n=2; data=new int*[m]; for(int j=0;j<m;j++) { data[j]=ne ...
- Java 数组操作
参考了网上别人的代码,在Java中对数组的比较便利的操作是 将数组转换成集合再利用集合所提供的add remove等方法进行增删,然后再转换成原数组类型 如 String[] --> 填充至 A ...
- Python学习教程(learning Python)--2.2.2 Python全局和局部变量
Python的变量也有全局和局部变量之分. 1. 局部变量 用在子函数里的变量称之为局部变量,其生命周期为该函数执行周期,即函数执行完后变量即不存在.由于局部变量和某个函数直接相关,故不同子函数里可以 ...
- Github上LeakCanary编译报错CreateProcess error=2的解决方法
现象说明: 从github上拉下LeakCanary编译时报错 CreateProcess error=2, ϵͳÕҲ»µ½ָ¶ 原因分析: 该现象是由于Windows中Gradle调用命令未加cmd ...