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 ...
随机推荐
- 洛谷 P4592: bzoj 5338: [TJOI2018]异或
题目传送门:洛谷P4592. 题意简述: 题面说的很清楚了. 题解: 发现没有修改很快乐.再看异或最大值操作,很容易想到可持久化 01trie. 这里要把 01trie 搬到树上,有点难受. 树剖太捞 ...
- Esper复杂事务处理一小时入门
来自小韩 什么是Esper 想要认识Esper,先要了解CEP(Complex Event Processing),到处都有,并且各方理解也有偏差,我就不赘述了. Esper就是CEP的一个java的 ...
- Hyperledger Fabric1.0.0搭建
系统环境: 阿里云新装的Centos7.2 yum -y update yum install -y openssl openssl-devel gcc gcc-c++ zlib zlib-devel ...
- 关于分布式存储系统中-CAP原则(CAP定理)与BASE理论比较
CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性). Availability(可用性).Partition tolerance(分区容错性),三者不可得兼. CA ...
- 列表选择Spinner
1.只用XML配置来显示列表 在res\values中添加一个arrays.xml 1 <?xml version="1.0" encoding="utf-8&qu ...
- 根据经纬度坐标计算距离-python
一.两个坐标之间距离计算 参考链接: python实现 1.Python 根据地址获取经纬度及求距离 2.python利用地图两个点的经纬度计算两点间距离 LBS 球面距离公式 美团app筛选“离我最 ...
- Scrapy官网程序执行示例
Windows 10家庭中文版本,Python 3.6.4,Scrapy 1.5.0, Scrapy已经安装很久了,前面也看了不少Scrapy的资料,自己尝试使其抓取微博的数据时,居然连登录页面(首页 ...
- java基础33 Set集合下的HashSet集合和TreeSet集合
单例集合体系: ---------| collection 单例集合的根接口--------------| List 如果实现了list接口的集合类,具备的特点:有序,可重复 注:集合 ...
- hdu 5475 模拟计算器乘除 (2015上海网赛H题 线段树)
给出有多少次操作 和MOD 初始值为1 操作1 y 表示乘上y操作2 y 表示除以第 y次操作乘的那个数 线段树的叶子结点i 表示 第i次操作乘的数 将1替换成y遇到操作2 就把第i个结点的值 替换成 ...
- js处理局部scroll事件禁止外部scroll滚动解决办法,jquery.mousewheel.js处理时禁止办法说明
js Code: <script> window.onload = function() { for (i = 0; i < 500; i++) { var x = document ...