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 ...
随机推荐
- weblogica domain目录 环境变量 如何启动weblogic server
手工启动weblogic server
- Memcache 内存分配策略和性能(使用)状态检查【转】
前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作. ...
- Python基础:获取平台相关信息
Windows 10家庭中文版,Python 3.6.4, 本文介绍了使用os.platform.sys三个模块获取Python程序的运行平台相关的信息. os模块:提供 各种各样的操作系统接口 os ...
- Dropout caffe源码
GPU和CPU实现的不一样,这里贴的是CPU中的drop out 直接看caffe里面的源码吧:(产生满足伯努利分布的随机数mask,train的时候,data除以p,...... scale_ = ...
- AdvStringGrid 获取值
stringGrid.row stringgrid.col分别为当前行和列 stringGrid.cells[stringgrid.col,stringGrid.row]就是当前cell的值 ---- ...
- SQL语句添加删除修改字段
用SQL语句添加删除修改字段1.增加字段 alter table docdsp add dspcodechar(200)2.删除字段 ALTER TABLE table_NAME ...
- Mac OS 下安装mysqlclient报“mysql_config not found”的解决
如问题所示,应该是你没有将mysql_config所在文件夹加入系统的PATH路径,解决方案下: 1.第一步找到你的mysql_config所在位置 1.1. 如果是直接安装mysql,所在位置应该是 ...
- Ubuntu 17.10开启 root 登陆
使用过 Ubuntu 的人都知道,Ubuntu 默认是不能以 root 登陆的,但是我们是不是就完全不能使用 root 进行登陆了呢?当然不是,只是我们需要做一些设置.而 Ubuntu 17.10 和 ...
- Ubuntu下编译安装OpenCV 2.4.7并读取摄像头
主要参考: 1.http://www.ozbotz.org/opencv-installation/ 2.http://www.ozbotz.org/opencv-install-troublesho ...
- 评分卡模型中的IV和WOE详解
1.IV的用途 IV的全称是Information Value,中文意思是信息价值,或者信息量. 我们在用逻辑回归.决策树等模型方法构建分类模型时,经常需要对自变量进行筛选.比如我们有200个候选 ...