您的位置:首页 > 其它

2019牛客暑期多校训练(第五场)C-generator 2

2019-08-09 21:49 204 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_43383246/article/details/98994599

2019牛客暑期多校训练(第五场)C-generator 2

题目描述

There is a sequence of length n:x0,x1,x2,…,xn−1. Please answer Q queries. Each query consists of one integer v, asking the minimum index i such that xi=v. If the sequence doesn’t have any number with value v, you only need to output -1.
Does the problem look simple? Surprise! The value of n may be as large as 1018!
Because n is so large. We will only give you four integers x0,a,b,p to generate the sequence. For all i>0, the sequence is generated as xi=(a⋅xi−1+b)mod p.

输入描述:

The first line of input contains an integer T (T≤4) denoting there are T tests in the input.
Each test contains Q+2 lines.
The first line of each test contains five integers n,x 0,a,b,p (1≤n≤1018,0≤xp,a,b<p≤109+9, p is a prime number).
The second line contains one integer Q (Q≤1000).
Each of the following Q lines contains one integer v (0≤v<p).

输出描述:

For each query, print one integer as the answer in one line.

示例1

输入
3
1000000009 1 1 1 1000000009
5
0
1
10
1000000008
1000000007
100000009 1 1 1 1000000009
3
0
10
1000000008
1000000000000000000 1 5 0 1000000007
6
0
1
10
1000000006
12345678
1234567
输出
1000000008
0
9
1000000007
1000000006
-1
9
-1
-1
0
381838283
500000003
652614354
581802189
说明
For the first test, the sequence looks like 1, 2, 3, …, 1000000008, 0. So the position of the first occurrence of value v is v - 1 except for value 0 which occurs at 1000000008.

示例2

输入
2
1000000000000000000 5 2 2 1000000007
4
0
1
2
3
5 1 0 3 950000017
4
0
1
2
3
输出
115068150
342074
115068151
-1
-1
0
-1
1

题意

已知x[i]=(a*x[i-1]+b)%p,求满足等式的x数组的下标,且该下标小于n。若不存在则输出-1。

思路

BSGS算法(北上广深算法,拔山盖世算法 )。
首先,我们可以根据递推式求出x
关于x[0]的表达式。
然后。。。然后。。。然后。。。
就没有然后了。
发现是一个BSGS的式子。
求就完了。

坑点

真特么多。
首先,这题时间卡的很紧,如果用map哈希的话很容易超时,所以我后来用了unordered_map。
然后,我队友用链式前向星手写哈希跑了627ms,tql。
大佬的CSDN个人主页
之后还加了很多小优化,具体的就看BSGS和initBSGS函数部分的代码吧。

代码

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N=1e5+5;

ll quickpow(ll a,ll b,ll mod)
{
ll ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}

unordered_map<int,int> M;
ll up,down,mul;

void initBSGS(ll y,ll p)
{
M.clear();
up=ceil(pow(p,2.0/3));
down=ceil(pow(p,1.0/3));
ll num=1;
for(int i=0; i<=up; i++)
{
if(i==up)
mul=num;
M[num]=i;
num=num*y%p;
}
}

ll BSGS(ll y,ll z,ll p)
{
ll num=quickpow(z,p-2,p);
for(int i=1; i<=down+1; i++)
{
num=num*mul%p;
if(M.count(num))
return i*up-M[num];
}
return -1;
}

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
ll n,x0,a,b,q,v,mod;
scanf("%lld%lld%lld%lld%lld",&n,&x0,&a,&b,&mod);
initBSGS(a,mod);
scanf("%lld",&q);
while(q--)
{
scanf("%lld",&v);
if(a==0)
{
if(v==x0)
printf("0\n");
else if(v==b&&n>=1)
printf("1\n");
else
printf("-1\n");
}
else if(a==1)
{
if(b==0)
printf("%d\n",v==x0?0:-1);
else
{
int invb=quickpow(b,mod-2,mod);
v=((v-x0+mod)%mod)*invb%mod;
printf("%d\n",v<n?v:-1);
}
}
else
{
if(x0==0&&b==0)
printf("%d\n",v==0?0:-1);
else
{
ll num=quickpow((((1-a+mod)%mod)*x0%mod-b+mod)%mod,mod-2,mod)*((((1-a+mod)%mod)*v%mod-b+mod)%mod)%mod;
ll ans=BSGS(a,num,mod);
if(ans<n)
printf("%lld\n",ans);
else
printf("-1\n");
}
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: