今天研究了一下这块内容...首先是板子

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 666666
template<class T>
inline T dw();
template<>
inline ll dw<ll>() {return 1;}
template<>
inline int dw<int>() {return 1;}
typedef pair<ll,ll> pll;
ll pll_s;
inline pll mul(pll a,pll b,ll p)
{
pll ans;
ans.fi=a.fi*b.fi%p+a.se*b.se%p*pll_s%p;
ans.se=a.fi*b.se%p+a.se*b.fi%p;
ans.fi%=p; ans.se%=p;
return ans;
}
inline ll mul(ll a,ll b,ll c)
{return a*b%c;}
//a^b mod c
template<class T>
T qp(T a,ll b,ll c)
{
T ans=dw<T>();
while(b)
{
if(b&1) ans=mul(ans,a,c);
a=mul(a,a,c); b>>=1;
}
return ans;
}
inline ll ll_rnd()
{
ll ans=0;
for(int i=1;i<=5;i++)
ans=ans*32768+rand();
if(ans<0) ans=-ans;
return ans;
}
//(x,y) -> x+sqrt(pll_s)*y
template<>
inline pll dw<pll>() {return pll(1,0);}
//find (possibly) one root of x^2 mod p=a
//correctness need to be checked
ll sqr(ll a,ll p)
{
if(!a) return 0;
if(p==2) return 1;
ll w,q;
while(1)
{
w=ll_rnd()%p;
q=w*w-a;
q=(q%p+p)%p;
if(qp(q,(p-1)/2,p)!=1)
break;
}
pll_s=q;
pll rst=qp(pll(w,1),(p+1)/2,p);
ll ans=rst.fi; ans=(ans%p+p)%p;
return ans;
}
//solve x^2 mod p=a
vector<ll> all_sqr(ll a,ll p)
{
vector<ll> vec;
a=(a%p+p)%p;
if(!a) {vec.pb(0); return vec;}
ll g=sqr(a,p);
ll g2=(p-g)%p;
if(g>g2) swap(g,g2);
if(g*g%p==a) vec.pb(g);
if(g2*g2%p==a&&g!=g2) vec.pb(g2);
return vec;
}
ll s3_a;
//f0+f1*x+f2*x^2 (for x^3=s3_a)
struct s3
{
ll s[3];
s3() {s[0]=s[1]=s[2]=0;}
s3(ll* p) {s[0]=p[0]; s[1]=p[1]; s[2]=p[2];}
s3(ll a,ll b,ll c) {s[0]=a; s[1]=b; s[2]=c;}
};
template<>
s3 dw<s3>() {return s3(1,0,0);}
s3 rs3(ll p)
{
return s3(ll_rnd()%p,ll_rnd()%p,ll_rnd()%p);
}
s3 mul(s3 a,s3 b,ll p)
{
ll k[3]={};
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
if(i+j<3) k[i+j]+=a.s[i]*b.s[j]%p;
else k[i+j-3]+=a.s[i]*b.s[j]%p*s3_a%p;
}
}
for(int i=0;i<3;i++) k[i]%=p;
return s3(k[0],k[1],k[2]);
}
//solve x^3 mod p=a
vector<ll> all_cr(ll a,ll p)
{
vector<ll> vec;
a=(a%p+p)%p;
if(!a) {vec.pb(0); return vec;}
if(p<=3)
{
for(int i=0;i<p;i++)
{
if(i*i*i%p==a) vec.pb(i);
}
return vec;
}
if(p%3==2)
{
vec.pb(qp(a,(p*2-1)/3,p));
return vec;
}
if(qp(a,(p-1)/3,p)!=1) return vec;
ll l=(sqr(p-3,p)-1)*qp(2LL,p-2,p)%p,x;
s3_a=a;
while(1)
{
s3 u=rs3(p);
s3 v=qp(u,(p-1)/3,p);
if(v.s[1]&&!v.s[0]&&!v.s[2])
{x=qp(v.s[1],p-2,p); break;}
}
x=(x%p+p)%p;
vec.pb(x); vec.pb(x*l%p); vec.pb(x*l%p*l%p);
sort(vec.begin(),vec.end());
return vec;
}
map<ll,ll> gg;
ll yss[2333]; int yyn=0;
//find x's primitive root
inline ll org_root(ll x)
{
ll& pos=gg[x];
if(pos) return pos;
yyn=0; ll xp=x-1;
for(ll i=2;i*i<=xp;i++)
{
if(xp%i) continue;
yss[++yyn]=i;
while(xp%i==0) xp/=i;
}
if(xp!=1) yss[++yyn]=xp;
ll ans=1;
while(1)
{
bool ok=1;
for(int i=1;i<=yyn;i++)
{
ll y=yss[i];
if(qp(ans,(x-1)/y,x)==1) {ok=0; break;}
}
if(ok) return pos=ans;
++ans;
}
}
map<ll,int> bsgs_mp;
//find smallest x: a^x mod p=b
ll bsgs(ll a,ll b,ll p)
{
if(b==0) return 1;
map<ll,int>& ma=bsgs_mp;
ma.clear();
//only /2.5 for speed...
ll hf=sqrt(p)/2.5+2,cur=b;
for(int i=0;i<hf;i++)
ma[cur]=i+1, cur=cur*a%p;
ll qwq=1,qh=qp(a,hf,p);
for(int i=0;;i++)
{
if(i)
{
if(ma.count(qwq))
return i*hf-(ma[qwq]-1);
}
qwq=qwq*(ll)qh%p;
}
return 1e18;
}
//ax+by=1
void exgcd(ll a,ll b,ll& x,ll& y)
{
if(b==0) {x=1; y=0; return;}
exgcd(b,a%b,x,y);
ll p=x-a/b*y; x=y; y=p;
}
template<class T>
T gcd(T a,T b) {if(b) return gcd(b,a%b); return a;}
//solve x^a mod p=b
vector<ll> kr(ll a,ll b,ll p)
{
vector<ll> rst;
if(!b) {rst.pb(0); return rst;}
ll g=org_root(p);
ll pb=bsgs(g,b,p);
ll b1=a,b2=p-1,c=pb;
ll gg=gcd(b1,b2);
if(c%gg) return rst;
b1/=gg, b2/=gg, c/=gg;
ll x1,x2; exgcd(b1,b2,x1,x2);
x1*=c; x1=(x1%b2+b2)%b2;
ll cs=qp(g,x1,p),ec=qp(g,b2,p);
for(ll cur=x1;cur<p-1;cur+=b2)
rst.pb(cs), cs=cs*ec%p;
sort(rst.begin(),rst.end());
return rst;
}

这份代码可以解决1014、1039、1038三道题。感人至深

参考链接是糖老师的这篇文章:http://blog.csdn.net/skywalkert/article/details/52591343?locationNum=3&fps=1

感觉二次和三次剩余里面已经讲得挺清楚了,注意三次剩余里面那个多项式群里面自变量取值是满足x^3=a的。

这里就讲一下k次剩余娱乐一下。

我们要解x^a mod p=b,p是个质数,那么p就有原根g。

考虑两边对原根g取log,设g^r=b,r可以用bsgs求出来,那么我们就是要求s*a mod (p-1)=r,那么x就等于g^s。

这个东西我们可以设s*a+qwq*(p-1)=r,先把(a,p-1)约分,用exgcd解出来一个s,然后就只要加上(约分后的p-1)的倍数就可以剩下的解了。

此外这题需要卡常,见bsgs函数里的/2.5。

二次剩余、三次剩余、k次剩余的更多相关文章

  1. 【51nod】1123 X^A Mod B (任意模数的K次剩余)

    题解 K次剩余终极版!orz 写一下,WA一年,bug不花一分钱 在很久以前,我还认为,数论是一个重在思维,代码很短的东西 后来...我学了BSGS,学了EXBSGS,学了模质数的K次剩余--代码一个 ...

  2. CF1106F Lunar New Year and a Recursive Sequence 线性递推 + k次剩余

    已知\(f_i = \prod \limits_{j = 1}^k f_{i - j}^{b_j}\;mod\;998244353\),并且\(f_1, f_2, ..., f_{k - 1} = 1 ...

  3. 第三次作业——K米评测

    第一部分 调研,评测 1.第一次上手体验 其实让我下载一个APP并且长期使用它是一件特别难的事情,不仅是因为占空间,需要注册个人信息,绑定账号,更是因为每款软件的功能虽然都很齐全,但是你并在没有真正用 ...

  4. 统计学习三:1.k近邻法

    全文引用自<统计学习方法>(李航) K近邻算法(k-nearest neighbor, KNN) 是一种非常简单直观的基本分类和回归方法,于1968年由Cover和Hart提出.在本文中, ...

  5. 统计学习三:2.K近邻法代码实现(以最近邻法为例)

    通过上文可知k近邻算法的基本原理,以及算法的具体流程,kd树的生成和搜索算法原理.本文实现了kd树的生成和搜索算法,通过对算法的具体实现,我们可以对算法原理有进一步的了解.具体代码可以在我的githu ...

  6. 系统服务监控指标--load、CPU利用率、磁盘剩余空间、磁盘I/O、内存使用情况等

    介绍 大型互联网企业的背后,依靠的是成千上万台服务器日夜不停的运转,以支撑其业务的运转.宕机对于互联网企业来说,代价是沉重的,轻则影响用户体验,重则直接影响交易,导致交易下跌,并且给企业声誉造成不可挽 ...

  7. 如何获取JavaCard剩余空间

    0x01应用场景 获取JavaCard卡内剩余空间,一方面是在评估一张卡的时候需要用到,另一方面是在应用个人化或者运行时需要用到. 例如:应用提供商为了保证自己的应用在卡内运行期间能够不受空间影响,一 ...

  8. JavaScript剩余操作符Rest Operator

    本文适合JavaScript初学者阅读 剩余操作符 之前这篇文章JavaScript展开操作符(Spread operator)介绍讲解过展开操作符.剩余操作符和展开操作符的表示方式一样,都是三个点 ...

  9. android计算每个目录剩余空间丶总空间以及SD卡剩余空间

    ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...

随机推荐

  1. javascript动画系列第三篇——碰撞检测

    前面的话 前面分别介绍了拖拽模拟和磁性吸附,当可视区域内存在多个可拖拽元素,就出现碰撞检测的问题,这也是javascript动画的一个经典问题.本篇将详细介绍碰撞检测 原理介绍 碰撞检测的方法有很多, ...

  2. Asp.net Boilerplate源码中NotNullAttribute的用处

    看Asp.net Boilerplate 1.1.3.0源码时发现有一个NotNullAttribute的定义和27处的引用,就是不知道它的作用,当然顾名思义是可以的,就是不知道它是怎么判断的,在哪里 ...

  3. iOS---iOS10适配iOS当前所有系统的远程推送

    一.iOS推送通知简介 众所周知苹果的推送通知从iOS3开始出现, 每一年都会更新一些新的用法. 譬如iOS7出现的Silent remote notifications(远程静默推送), iOS8出 ...

  4. PC分配盘符的时候发现==》RPC盘符不可用

    服务器汇总:http://www.cnblogs.com/dunitian/p/4822808.html#iis 服务器异常: http://www.cnblogs.com/dunitian/p/45 ...

  5. js获取给定月份的N个月后的日期

    1.在讲js获取给定月份的N个月后的日期之前,小颖先给大家讲下getFullYear().getYear()的区别. ①getYear() var d = new Date() console.log ...

  6. 伪共享(false sharing),并发编程无声的性能杀手

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  7. MVC常遇见的几个场景代码分享

    本次主要分享几个场景的处理代码,有更好处理方式多多交流,相互促进进步:代码由来主要是这几天使用前端Ace框架做后台管理系统,这Ace是H5框架里面的控件效果挺多的,做兼容也很好,有点遗憾是控件效果基本 ...

  8. 操作系统篇-hello world(免系统运行程序)

     || 版权声明:本文为博主原创文章,未经博主允许不得转载. 一.前言     今天起开始分享关于操作系统的相关知识,本人也是菜鸟一个,正处于学习阶段,这整个操作系统篇也是我边学习边总结的一些结果,希 ...

  9. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  10. WebSocket - ( 一.概述 )

    说到 WebSocket,不得不提 HTML5,作为近年来Web技术领域最大的改进与变化,包含CSS3.离线与存储.多媒体.连接性( Connectivity )等一系列领域,而即将介绍的 WebSo ...