您的位置:首页 > 其它

[BZOJ3122][Sdoi2013]随机数生成器(快速幂+BSGS)

2016-03-02 19:14 387 查看

题目描述

传送门

题解

先说一下暴力的写法,这道题最好是写一个小暴力拍一下:

按照题目描述的枚举即可,但是要注意判断无解的条件。通过观察可以发现这个数列是存在循环节的,如果已经找到了循环节并且第一个循环节内没有满足条件的xn那么就可以直接退出啦。

正解的话应该是把这个式子变一下形然后做BSGS,推倒如下:

原式可以化为:Xi+1≡aXi+b(modp)

Xi+1+ba−1≡aXi+b+ba−1(modp)

Xi+1+ba−1≡a(Xi+ba−1)(modp)



Xn+ba−1≡a(Xn−1+ba−1)(modp)……①

Xn−1+ba−1≡a(Xn−2+ba−1)(modp)……②

讲②代人①得到

Xn+ba−1≡a2(Xn−2+ba−1)(modp)

很神奇啊对不对,迭代下去

于是我们可以得到:

Xn+ba−1≡an−1(X1+ba−1)(modp)

我们发现,除了an−1之外,其余各项都是常数,于是

an−1≡(Xn+b∗inv(a−1))∗inv(X1+b∗inv(a−1))(modp)

其中inv为某数的逆元。

用BSGS算法求n-1即可

需要注意的一些小问题:

①在同余式中除以一个数等于乘以这个数的逆元。在模p意义下a的逆元为ap−2,这个可以通过费马小定理证明。

②因为满足0<=a,b,x1<=p-1,且p为质数,那么一定满足a-1和p互质,那么我们就可以用快速幂求a-1的逆元啦。

③一些特殊情况需要特判

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
#define LL long long

LL T,P,a,b,x1,t;
LL ny1,ny2,val1,val2,val3;
LL ans;
map <LL,LL> hash;

inline LL fast_pow(LL a,LL p){
LL ans=1;
for (;p;p>>=1,a=a*a%P)
if (p&1)
ans=ans*a%P;
return ans;
}

inline LL BSGS(LL a,LL b){
LL m=ceil(sqrt(P));
LL a_m=fast_pow(a,m);
hash.clear();

LL mul=1;
LL val=mul*b%P;
hash[val]=0;
for (LL j=1;j<=m;++j){
mul=mul*a%P;
val=mul*b%P;
hash[val]=j;
}

mul=1;
for (LL i=1;i<=m;++i){
mul=mul*a_m%P;
if (hash[mul]){
LL x=i*m-hash[mul];
return x+1;
}
}
return -1;
}

int main(){
scanf("%lld",&T);
while (T--){
scanf("%lld%lld%lld%lld%lld",&P,&a,&b,&x1,&t);

//一坨特判
if (t==x1){
printf("1\n");
continue;
}
if (a==0){
if (t==b) printf("2\n");
else printf("-1\n");
continue;
}
if (a==1&&b==0){
printf("-1\n");
continue;
}
if (a==1){
int nyb=fast_pow(b,P-2);
ans=((((t-x1)%P+P)%P)*nyb%P)%P;
printf("%lld\n",ans+1);
continue;
}

ny1=fast_pow(a-1,P-2);
val1=b*ny1%P;

val2=(x1%P+val1)%P;
ny2=fast_pow(val2,P-2);

val3=(t+val1)%P;
b=(val3*ny2)%P;

ans=BSGS(a,b);
printf("%lld\n",ans);
}
}


总结

①注意负数的情况。

②先%后+还是先+后%想清楚。在纸上列列公式,实在不行先换元。

③在%p意义下a的逆元为ap−2,ap互质且p为质数,不要搞错了。

④其实这道题是在式子的两边同时加上了一个常数,然后化成通项公式。也就是找出X1和Xn的关系。这样的话要保证X1和Xn的系数相等(把a提出),且可以一直推下去(也就是说保证式子左边的一坨和右边除去系数的一坨相同,则同时加上的常数可以计算出来)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: