sgu 261
学习了元根的一些知识,哈哈。
总结一下:
几个概念:
阶:对于模数m和整数a,并且gcd(m,a)==1,那么定义a在模m下的阶r为满足ar=1 mod m的最小正整数。
性质1:r in [1,phi(m)] (由欧拉定理)
性质2:r | phi(m) ( ar=aphi(m) mod m,然后用反证法)
性质3:r 是整数a模m的阶当且仅当满足:1)ar=1 mod m 2) a r/p(r) ≠ 1 mod m (后面推前面也用反正法)。
元根:
如果对于一个模数m,存在一个数a,满足a在模m下的阶是phi(m),那么就称a是模数m的一个元根。
性质:所有质数有元根(更一般的,2,4,pe,2pe有元根,p是奇质数)
元根应用
元根依靠离散对数,将对数运算引入了模数的缩系下。从而可以解决很多数论中关于指数的问题。
indga=indgb mod phi(m) <=> a=b mod m
indgak=k indga mod phi(m)
indgab=indga+indgb mod phi(m)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std; typedef long long dnt; const int mod = ;
const int elen = ;
struct Hash {
int head[mod], val[elen], rat[elen], next[elen], etot;
void init() {
memset( head, , sizeof(head) );
etot = ;
}
void insert( int v, int r ) {
int k = v % mod;
etot++;
next[etot] = head[k];
rat[etot] = r;
val[etot] = v;
head[k] = etot;
}
int query( int v ) {
int k = v % mod;
for( int t=head[k]; t; t=next[t] )
if( val[t]==v ) return rat[t];
return -;
}
}hash; int p, a, k;
int g, b;
vector<int> stk; dnt mpow( dnt a, int b, int m ) {
dnt rt;
for( rt=; b; b>>=,a=(a*a)%m )
if( b& ) rt=(rt*a)%m;
return rt;
}
void exgcd( int a, int b, int &d, dnt &x, dnt &y ) {
if( b== ) d=a, x=, y=;
else {
exgcd( b, a%b, d, y, x );
y-=a/b*x;
}
}
int gcd( int a, int b ) {
return b ? gcd(b,a%b) : a;
}
int findroot( int n ) { // n is prime
if( n== ) return ; vector<int> pfac;
int maxi = (int)ceil(sqrt(n-));
int remain=n-;
for( int i=; i<=maxi; i++ ) {
if( remain%i== ) {
pfac.push_back(i);
while( remain%i== )
remain/=i;
}
}
if( remain!= ) pfac.push_back( remain );
for( int i=; ; i++ ) {
bool ok = true;
for( int t=; t<pfac.size(); t++ )
if( mpow(i,(n-)/pfac[t],n)== ) {
ok = false;
break;
}
if( ok ) return i;
}
}
dnt inv( int a, int n ) {
return mpow(a,n-,n);
}
dnt ind( int g, int b, int n ) { // n is prime, g is root, return v in [0,n-1]
hash.init();
int m = (int)ceil(sqrt(n-));
dnt s = ;
for( int i=; i<m; i++ ) {
if( s==b ) return i;
hash.insert( s, i );
s = (s*g) % n;
}
int am = s;
s = b;
for( int i=m,j; i<n; i+=m ) {
s = (s*inv(am,n)) % n;
if( (j=hash.query(s))!=- )
return i+j;
}
return -; // impossible
}
void meq( int a, int b, int m ) {
stk.clear();
int d = gcd(a,m);
if( b%d ) return;
int aa=a/d, bb=b/d, mm=m/d, dd;
dnt x0, y0;
exgcd( aa, mm, dd, x0, y0 );
x0 = (x0%mm+mm)%mm;
for( dnt k=; k<d; k++ )
stk.push_back( (x0*bb+k*mm)%m );
} int main() {
scanf( "%d%d%d", &p, &k, &a ); // x^k = a mod p
if( a== ) {
printf( "1\n0 \n" );
return ;
}
// find the root of p: g
g = findroot(p);
// ind a: b
b = ind( g, a, p );
// kx=b mod phi(p)
meq( k, b, p- );
// decode
for( int t=; t<stk.size(); t++ )
stk[t] = mpow( g, stk[t], p );
sort( stk.begin(), stk.end() );
// output
printf( "%d\n", stk.size() );
for( int t=; t<stk.size(); t++ )
printf( "%d ", stk[t] );
printf( "\n" );
}
sgu 261的更多相关文章
- SGU 261. Discrete Roots (N次剩余)
N次剩余 题目:http://acm.sgu.ru/problem.php? contest=0&problem=261 题意:给定n,a,p 求出x^n ≡ a(mod p)在模p意义下的全 ...
- SGU 261. Discrete Roots
给定\(p, k, A\),满足\(k, p\)是质数,求 \[x^k \equiv A \mod p\] 不会... upd:3:29 两边取指标,是求 \[k\text{ind}_x\equiv ...
- 一些数论概念与算法——从SGU261谈起
话说好久没来博客上面写过东西了,之前集训过于辛苦了,但有很大的收获,我觉得有必要把它们拿出来总结分享.之前一直是个数论渣(小学初中没好好念过竞赛的缘故吧),经过一道题目对一些基础算法有了比较深刻的理解 ...
- java.lang.IllegalArgumentException: Illegal character in query at index 261
在BaseFragment中使用了LoadingPage,而LoadingPage的联网加载使用的是AsyncHttpClient.一直报java.lang.IllegalArgumentExcept ...
- Codeforces #261 D
Codeforces #261 D D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per te ...
- SGU 495. Kids and Prizes
水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...
- ACM: SGU 101 Domino- 欧拉回路-并查集
sgu 101 - Domino Time Limit:250MS Memory Limit:4096KB 64bit IO Format:%I64d & %I64u Desc ...
- 【SGU】495. Kids and Prizes
http://acm.sgu.ru/problem.php?contest=0&problem=495 题意:N个箱子M个人,初始N个箱子都有一个礼物,M个人依次等概率取一个箱子,如果有礼物则 ...
- SGU 455 Sequence analysis(Cycle detection,floyd判圈算法)
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=455 Due to the slow 'mod' and 'div' operati ...
随机推荐
- socket相关系统调用的调用流程
最近一直在读内核网络协议栈源码,这里以ipv4/tcp为例对socket相关系统调用的流程做一个简要整理,这些相关系统调用的内部细节虽然各有不同,但其调用流程则基本一致: 调用流程: (1)系统调用 ...
- asp.net操作word 配置在IIS上出现的问题
异常: 检索 COM 类工厂中 CLSID 为 {000209FF-0000-0000-C000-000000000046} 的组件失败,原因是出现以下错误: 80070005 拒绝访问. (异常来自 ...
- 006_Mac下sublime text 的“package control”安装,sublimepackage
Mac下sublime text 的“package control”安装,sublimepackage 小伙伴们好,我根据昨晚的经历写一个小总结:关于“Mac下sublime text 的“pack ...
- 说一下怎么搭建外网来访问SVN服务器
一.搭建SVN服务器 1.所需软件 TortoiseSVN,下载地址http://tortoisesvn.net/downloads.html TortoiseSVN中文语言包,下载地址http:// ...
- mysql命令gruop by报错this is incompatible with sql_mode=only_full_group_by
在mysql 工具 搜索或者插入数据时报下面错误: ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause ...
- 浮动元素垂直居中,bootstrap栅格布局垂直居中
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javaweb作业二
作业:1.书写servlet的类架构及重要方法.(ServletConfig,Servlet)<---GenericServlet(getInitParameter(String str);in ...
- (三)Jsoup 使用选择器语法查找 DOM 元素
第一节: Jsoup 使用选择器语法查找 DOM 元素 Jsoup使用选择器语法查找DOM元素 我们前面通过标签名,Id,Class样式等来搜索DOM,这些是不能满足实际开发需求的, 很多时候我们需要 ...
- 20155225 2016-2017-2《Java程序设计》课程总结
20155225 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:新的开始 预备作业2:C语言学习回顾 预备作业3:Linux基础入门和虚拟机的安装 第一 ...
- JavaScript中构造函数
构造函数:函数的另一种执行方法,执行后创建对象,并创建原型对象. 原型链:对象访问构造函数的指针. Function函数:函数对象. Object函数:所有创建对象的祖辈对象,也是由Function对 ...