2019牛客多校第五场generator2——BSGS&&手写Hash
题目
几乎原题 BZOJ3122题解
分析
先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法。
在标准的BSGS中,内外层循环都是 $\sqrt p$,题目查询 $m$ 次,$m \leq 1000$,$ p \leq 10^9$,这样总时间复杂度为 $O(m \sqrt p)$,勉强能接受。据说使用读入优化和手写哈希还是能过得,可见Cls的代码%%%
仔细想一下,由于BSGS分成两步,其中第一步是建立 $a$ 的幂次方的表,而题恰好是 $a,p$相同下的一组询问,所以这一部分可以与处理。
显然,我们应该对这部分分大点,第二步就会小写(因为积一定),
如分成 $\sqrt {mp} \times \sqrt{\frac{p}{m}}$(前面是预处理时间,后面是每次查询的时间)
也可以是 $\frac{p}{1000} \times 1000$,总之,要是预处理部分大一点。
- #include<bits/stdc++.h>
- #define rep(i,a,n) for(int i=a;i<=n;i++)
- #define per(i,a,n) for(int i=n;i>=a;i--)
- #define pb push_back
- #define mp make_pair
- #define FI first
- #define SE second
- #define maxn 100000
- #define inf 0x3f3f3f3f
- using namespace std;
- typedef long long ll;
- typedef unsigned long long ull;
- typedef pair<int,int> pii;
- typedef vector<int> vi;
- typedef double db;
- int mod;
- int m=;
- const int M=;
- int hs[M],head[M],nxt[M],id[M],top;
- void insert(int x,int y)
- {
- int k=x%M;
- hs[top]=x,id[top]=y,nxt[top]=head[k],head[k]=top++;
- }
- int find(int x)
- {
- int k=x%M;
- for(int i=head[k];i!=-;i=nxt[i]) if(hs[i]==x) return id[i];
- return -;
- }
- int BSGS(int a,int b,int n)
- {
- if(b==) return ;
- ll p=;
- int ans=inf;
- rep(i,,m)
- {
- int id=find(1ll*p*b%n);
- if(id!=-) ans=min(ans,id-i);
- p=p*a%mod;
- }
- if(ans==inf) return -;
- return ans;
- }
- ll qp(ll a,ll k)
- {
- ll res=;
- while(k)
- {
- if(k&) res=res*a%mod;
- a=a*a%mod;
- k>>=;
- }
- return res;
- }
- ll _inv(ll x) {return qp(x,mod-);}
- int main()
- {
- int CAS; scanf("%d",&CAS);
- while(CAS--)
- {
- ll N; int x0,a,b; scanf("%lld%d%d%d%d",&N,&x0,&a,&b,&mod);
- memset(head,-,sizeof head); top=;
- int bn=(mod+m-)/m;
- int aA=qp(a,m),pw=aA;
- rep(i,,bn)
- {
- if(find(pw)==-) insert(pw,i*m);
- pw=1ll*pw*aA%mod;
- }
- int Q; scanf("%d",&Q);
- while(Q--)
- {
- int v; scanf("%d",&v);
- if(a==)
- {
- if(v==x0) puts("");
- else if(v==b)
- {
- if(N==) puts("-1");
- else puts("");
- }
- else puts("-1");
- }
- else if(a==)
- {
- if(b==)
- {
- if(v==x0) puts("");
- else puts("-1");
- }
- else
- {
- ll n=1ll*(v+mod-x0)*_inv(b)%mod;
- if(n>=N) puts("-1");
- else printf("%lld\n",n);
- }
- }
- else
- {
- v=(1ll*(a-)*v+b)%mod;
- int X=(1ll*(a-)*x0+b)%mod;
- if(X==)
- {
- if(v==) puts("");
- else puts("-1");
- }
- else
- {
- v=1ll*v*_inv(X)%mod;
- if(v==) puts("-1");
- else
- {
- int n=BSGS(a,v,mod);
- if(n>=N) puts("-1");
- else printf("%d\n",n);
- }
- }
- }
- }
- }
- return ;
- }
参考链接:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=41008097
2019牛客多校第五场generator2——BSGS&&手写Hash的更多相关文章
- 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂
理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...
- 2019牛客多校第五场F maximum clique 1 最大独立集
题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...
- 2019牛客多校第五场G-subsequence 1 DP
G-subsequence 1 题意 给你两个字符串\(s.t\),问\(s\)中有多少个子序列能大于\(t\). 思路 令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长 ...
- 2019牛客多校第五场 B - generator 1 矩阵快速幂+十倍增+二进制倍增优化
B - generator 1 题意 给你\(x_{0}.x_{1}.a.b.b.mod\),根据\(x_{i} = a*x_{i-1} + b*x_{i-2}\)求出\(x_{n}\) 思路 一般看 ...
- 2019牛客多校第五场H - subsequence 2 拓扑
H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...
- 2019牛客多校第五场B-generator 1(矩阵快速幂)
generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...
- 2019 牛客多校第五场 B generator 1
题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...
- 2019牛客多校第五场 G subsequence 1 dp+组合数学
subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...
- 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集
maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...
随机推荐
- 使用网关zuul过滤器登录鉴权
使用网关zuul过滤器登录鉴权 1.新建一个filter包 filte有很多种 pre.post. 2.新建一个类LoginFilter,实现ZuulFilter,重写 ...
- Python使用datetime来判断近七天
目录 strptime 使用strptime来格式化字符串 datetime.datetime.strptime("2019-10-02", "%Y-%m-%d" ...
- 【规律】Parentheses
Parentheses 题目描述 Dave loves strings consisting only of '(' and ')'. Especially, he is interested in ...
- PHP对程序员的要求更高
我这个文章标题可不是和大家开玩笑的哦 首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译.. 为此, 也 ...
- html如何点击子元素事件而不触发父元素的点击事件——阻止冒泡
如果子元素和父元素都有点击事件,会出现点击事件冒泡的情况. 1.如何避免冒泡: html: <html> <head></head> <body> &l ...
- jvm类加载原理和类加载器介绍
虚拟机的类加载机制 在Class文件中描述的各种信息最终都需要加载到虚拟机中之后才能运行和使用. 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换解析和初始化,最终形成可以被 ...
- Angular 调试
我们新建一个项目.执行 ng server 会启动一个网站. 1. 执行 where ng .看看ng 是什么. D:\Abp学习\angular\Mytest>where ng C:\User ...
- [Vuex系列] - Actions的理解之我见
Actions如何定义的 恕小端不才,对Action的总结如下: Action 可以提交mutation方法,通过mutation来改变state Action 函数可以接收一个context对象,通 ...
- vue 的虚拟 DOM 有什么好处?
vue 中的虚拟DOM有什么好处?快! 首先了解浏览器显示网页经历的5个过程 1.解析标签,生成元素树(DOM树) 2.解析样式,生成样式树 3.生成元素与样式的关系 4.生成元素的显示坐标 5.显示 ...
- 用python实现新词发现程序——基于凝固度和自由度
互联网时代,信息产生的数量和传递的速度非常快,语言文字也不断变化更新,新词层出不穷.一个好的新词发现程序对做NLP(自然预言处理)来说是非常重要的. N-Gram加词频 最原始的新词算法莫过于n-gr ...