题目

几乎原题 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. Target Sum

    You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symb ...

  2. PAT甲级 图的遍历 相关题_C++题解

    图的遍历 PAT (Advanced Level) Practice 图的遍历 相关题 目录 <算法笔记>重点摘要 1021 Deepest Root (25) 1076 Forwards ...

  3. 人机交互技术 Week 1_人机交互概述

    HCI Week 1_Introduction 18-19学年春夏学期选修了计院万华根老师的人机交互技术课程,老师由于知识产权相关原因不能提供课件,故尽可能对课程内容做详尽的课堂笔记以供复习,如有不妥 ...

  4. 20190705-Python数据驱动之DDT

    DDT ddt 是第三方模块,需安装, pip install ddt DDT包含的装饰器 包含一个类装饰器@ddt和两个方法装饰器@data和@file_data 通常情况下,@data中的数据按照 ...

  5. PAT(B) 1012 数字分类(Java)

    题目链接:1012 数字分类 代码 /** * Score 20 * Run Time 142ms * @author wowpH * @version 1.1 */ import java.util ...

  6. 十二、使用PWM调整LCD背光亮度

    和手机一样,开发板中也带有调整背光亮度的功能. 调整背光亮度依赖于PWM,它通过调节脉冲宽度来控制背光亮度,此方式需要使用PWM驱动.本章将对其进行讲解. 一.用户空间调整背光亮度 一般应用程序可以通 ...

  7. python 虚拟环境 venv 简单用法

    Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替Python之前的virtualenv.该venv模块提供了创建轻量级“虚拟环境”,提供与系统Python的隔离支持.每一个虚拟环 ...

  8. 导入别的项目到我的eclipse上出现红色感叹号问题

        项目红色感叹号问题问题 一般我们在导入别的项目到我的eclipse上面会发现,项目上面有红色的错误     原因 因为我电脑上的 jdk版本和别人电脑jdk版本不一样,那么对于的jre版本也不 ...

  9. (六)Redis之数据结构之sorted-set

    一.常用方法 Sorted-Set和Set的区别 Sorted-Set中的成员在集合中的位置是有序的 添加元素 获得元素 删除元素 范围查询 1和2和3和4 添加/获得/删除元素/范围查询 packa ...

  10. 【原创】大叔经验分享(85)ssh秘钥之创建和使用

    一 创建秘钥 1 Macbook $ ssh-keygen -t rsaGenerating public/private rsa key pair.Enter file in which to sa ...