题目

几乎原题 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的更多相关文章

  1. 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂

    理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...

  2. 2019牛客多校第五场F maximum clique 1 最大独立集

    题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...

  3. 2019牛客多校第五场G-subsequence 1 DP

    G-subsequence 1 题意 给你两个字符串\(s.t\),问\(s\)中有多少个子序列能大于\(t\). 思路 令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长 ...

  4. 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}\) 思路 一般看 ...

  5. 2019牛客多校第五场H - subsequence 2 拓扑

    H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...

  6. 2019牛客多校第五场B-generator 1(矩阵快速幂)

    generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...

  7. 2019 牛客多校第五场 B generator 1

    题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...

  8. 2019牛客多校第五场 G subsequence 1 dp+组合数学

    subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...

  9. 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集

    maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...

随机推荐

  1. HashSet和HashMap

    HashMap 概念和特征  概念:以键值对的形式存储数据,由键映射到值,核心在于Key上.  特征:键不能重复,值可以重复:key-value允许为null.     HashMap   Since ...

  2. Windows10下安装numpy

    1.https://bootstrap.pypa.io/get-pip.py 下载get-pip.py(右键另存为即可) 2.命令行下在get-pip.py所在文件夹下运行get-pip.py 3.命 ...

  3. uboot-的start.S详细注解及分析

    原文地址:uboot-的start.S详细注解及分析 作者:zhouyg11 大多数bootloader都分为stage1和stage2两部分,u-boot也不例外.依赖于CPU体系结构的代码(如设备 ...

  4. (四)Decorator设计模式解决GET/POST请求的乱码问题(转)

    一.Decorator设计模式 1.1.Decorator设计模式介绍 当某个对象的方法不适应业务需求时,通常有2种方式可以对方法进行增强: 编写子类,覆盖需增强的方法. 使用Decorator设计模 ...

  5. 双重检查加锁机制(并发insert情况下数据重复插入问题的解决方案)

    双重检查加锁机制(并发insert情况下数据重复插入问题的解决方案) c#中单例模式和双重检查锁 转:https://blog.csdn.net/zhongliangtang/article/deta ...

  6. 正则限制input负数输入

    //直接在input标签内加入下面两个事件处理程序即可 onkeyup="this.value=this.value.replace(/\D|^0/g,'')" onafterpa ...

  7. Java 之 可变参数

    可变参数 在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式: 修饰符 返回值类型 方法名(参数类型... 形参名){ } 其实这个书写完全等价 ...

  8. 8.读写锁ReadWriteLock

    /*ReadWriteLock 读写锁*/ private ReadWriteLock lock = new ReentrantReadWriteLock(); lock.readLock().loc ...

  9. 深度学习_1_Tensorflow_2_数据_文件读取

    tensorflow 数据读取 队列和线程 文件读取, 图片处理 问题:大文件读取,读取速度, 在tensorflow中真正的多线程 子线程读取数据 向队列放数据(如每次100个),主线程学习,不用全 ...

  10. lvs 中的DR模式 ,解释

    CIP即为客户端的IP地址 . DIR为调度器 . VIP为虚拟IP地址 . RIP为真实服务器IP地址 . 假设CIP的mac为A1,ip为B1:DIR只有一个物理网卡mac为A2,IP为B2:RI ...