3122: [Sdoi2013]随机数生成器

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 1442  Solved: 552

Description

Input

输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数。

接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据。保证X1和t都是合法的页码。

注意:P一定为质数

Output

共T行,每行一个整数表示他最早读到第t页是哪一天。如果他永远不会读到第t页,输出-1。

Sample Input

3
7 1 1 3 3
7 2 2 2 0
7 2 2 2 1

Sample Output

1
3
-1

HINT

0<=a<=P-1,0<=b<=P-1,2<=P<=10^9

【分析】

  这题简直坑爹到家了!!p是质数不说,还有各种恶心特判!!!!

  a=0,a=1,b=0都要特判。

  虽说自己推出了通项公式,但是哪里的除法可以逆元哪里不可以都不知道,一开始通分各种wa!!

  看别人的题解吧:

已知xn=a*xn-1+b%p,求最小的n令xn=t

首先,若x1=t,则返回1

若a=0,则若b=t 返回2,否则无解

若a=1,则T=t-x1+p%p,可以列出方程

b*x+p*y==T % p

若a>=2,则根据等比数列和可得

xn=t=x1*a^(n-1)+b*(a^(n-1)-1)/(a-1) %p

由于p为质数,所以令c=inv[a-1]=(a-1)^(p-2)

x1*a^(n-1)+b*c*(a^(n-1))==b*c+t %p

(x1+b*c)*(a^(n-1))==b*c+t % p

令A=x1+b*c,B=p,C=b*c+t

则就是解A*X+B*Y==C %p

解出来X=a^(n-1),然后这个用BSGS求就可以了

http://www.cnblogs.com/qzqzgfy/p/5581955.html

我的代码:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define LL long long
#define Maxn 35000 struct node
{
LL id,val;
}t[Maxn]; LL ax,ay;
LL exgcd(LL a,LL b)
{
if(b==) {ax=;ay=;return a;}
LL g=exgcd(b,a%b);
LL xx=ax;
ax=ay;ay=xx-(a/b)*ay;
return g;
} bool cmp(node x,node y) {return (x.val==y.val)?(x.id<y.id):(x.val<y.val);} LL cnt; LL t_div(LL x)
{
LL l=,r=cnt;
while(l<r)
{
LL mid=(l+r)>>;
if(t[mid].val==x) return t[mid].id;
if(t[mid].val>x) r=mid-;
else l=mid+;
}
if(t[l].val==x) return t[l].id;
return -;
} LL get_ans(LL k,LL a,LL c,LL p)
{
LL sq=(LL)ceil(sqrt((double)p));
t[].id=;t[].val=k%p;
for(LL i=;i<=sq;i++) t[i].val=(t[i-].val*a)%p,t[i].id=i; sort(t+,t++sq,cmp);
cnt=;
for(LL i=;i<=sq;i++) if(t[i].val!=t[i-].val) t[++cnt]=t[i]; LL bm=;
for(LL i=;i<=sq;i++) bm=(bm*a)%p;
LL g=exgcd(bm,p);
ax=(ax%(p/g)+(p/g))%(p/g);
bm=ax; LL tmp=c%p;
for(LL i=;i<=sq;i++)
{
LL now=t_div(tmp);
if(now!=-) return now+i*sq;
tmp=(tmp*bm)%p;
}
return -;
} LL ffind(LL k,LL a,LL c,LL p)
{
LL x=k;
for(LL i=;i<=;i++)
{
if(x==c) return i;
x=(x*a)%p;
}
LL g;
x=;
while((g=exgcd(a,p))!=)
{
p/=g;
k=(k*(a/g))%p;
if(c%g!=) return -;
c/=g;
x++;
}
LL ans=get_ans(k,a,c,p);
if(ans==-) return -;
return ans+x;
} int main()
{
int T,kase=;
scanf("%d",&T);
while(T--)
{
// printf("%d: ",++kase);
LL p,a,b,x,t,c;
scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x,&t);
// if(b==0) {printf("1\n");continue;}
if(t==x) {printf("1\n");continue;}
if(a==&&b==t) {printf("2\n");continue;}
else if(a==) {printf("-1\n");continue;}
if(a==)
{
LL g=exgcd(b,p);
c=t-x;c=(c%p+p)%p;
if(c%g!=) {printf("-1\n");continue;}
ax*=c/g;
ax=(ax%(p/g)+(p/g))%(p/g);
printf("%d\n",ax+);
continue;
} LL phi;
if(b%(a-)==) phi=b/(a-);
else
{
if(exgcd(a-,p)!=) {printf("-1\n");continue;}
ax=(ax%p+p)%p;
phi=(b*ax)%p;
}
LL A=x+phi,B=phi+t; if(b==) A=x,B=t; A=(A%p+p)%p; B=(B%p+p)%p;
// if(A==0) {printf("-1\n");continue;} LL ans=ffind(A,a,B,p); if(ans==-) printf("-1\n");
else printf("%lld\n",ans+);
}
return ;
}

BZOJ 3211

2016-09-05 18:24:44

【BZOJ 3122】 [Sdoi2013]随机数生成器 (BSGS)的更多相关文章

  1. bzoj 3122 : [Sdoi2013]随机数生成器 BSGS

    BSGS算法 转自:http://blog.csdn.net/clove_unique 问题 给定a,b,p,求最小的非负整数x,满足$a^x≡b(mod \ p)$ 题解 这就是经典的BSGS算法, ...

  2. Bzoj 3122 [Sdoi2013]随机数生成器(BSGS+exgcd)

    Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数. 接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. 注意:P一定为质数 Outp ...

  3. bzoj 3122 [Sdoi2013]随机数生成器(逆元,BSGS)

    Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数.    接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据.保证X1和t都是合法的页码. ...

  4. bzoj 3122: [Sdoi2013]随机数生成器【BSGS】

    题目要求的是: \[ ...a(a(a(ax+b)+b)+b)+b...=a^nx+a^{n-1}b+a^{n-2}b+...+b\equiv t(mod\ p) \] 后面这一大坨看着不舒服,所以考 ...

  5. bzoj 3122: [Sdoi2013]随机数生成器

    #include<cstdio> #include<iostream> #include<map> #include<cmath> #define ll ...

  6. 【BZOJ3122】[Sdoi2013]随机数生成器 BSGS+exgcd+特判

    [BZOJ3122][Sdoi2013]随机数生成器 Description Input 输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数.   接下来T行,每行有五个整数p,a,b, ...

  7. BZOJ3122: [Sdoi2013]随机数生成器(BSGS)

    题意 题目链接 Sol 这题也比较休闲. 直接把\(X_{i+1} = (aX_i + b) \pmod P\)展开,推到最后会得到这么个玩意儿 \[ a^{i-1} (x_1 + \frac{b}{ ...

  8. 【bzoj3122】[Sdoi2013]随机数生成器 BSGS思想的利用

    题目描述 给出递推公式 $x_{i+1}=(ax_i+b)\mod p$ 中的 $p$.$a$.$b$.$x_1$ ,其中 $p$ 是质数.输入 $t$ ,求最小的 $n$ ,使得 $x_n=t$ . ...

  9. [bzoj3122][SDOI2013]随机数生成器 ——BSGS,数列

    题目大意 给定递推序列: F[i] = a*F[i-1] + b (mod c) 求一个最小的i使得F[i] == t 题解 我们首先要化简这个数列,作为一个学渣,我查阅了一些资料: http://d ...

随机推荐

  1. openwrt chinadns

    opkg update opkg install ip ipset resolveip iptables-mod-tproxy resolveip libopenssl luci-i18n-base- ...

  2. Apache Commons Beanutils对象属性批量复制(pseudo-singleton)

    Apache Commons Beanutils为开源软件,可在Apache官网http://commons.apache.org/proper/commons-beanutils/download_ ...

  3. Windows 7 SP1 x64 旗舰版 微软官方安装U盘的制作

    [ 本主题由 中山艹泥喵 于 2013-08-20 23:14:33 设为精华1,原因:不错~ ] 最后由 风中枯萎 于 2015-12-15 17:44:15 修改 安装Windows 7操作系统主 ...

  4. MySQL的链接,查看数据库,使用数据库,查看表

    MySQL的链接,查看数据库,使用数据库,查看表 mysql> show databases; +--------------------+ | Database | +------------ ...

  5. 那天有个小孩跟我说LINQ(二)转载

    1  LINQ TO Objects续(代码下载)      新建项目 linq_Ch2控制台程序,新建一个Entity文件夹    1.1 学生成绩查询(练习Join)         有三张表如下 ...

  6. Java并发编程:进程和线程之由来__进程让操作系统的并发性成为可能,而线程让进程的内部并发成为可能

    转载自海子:http://www.cnblogs.com/dolphin0520/p/3910667.html Java多线程基础:进程和线程之由来 在前面,已经介绍了Java的基础知识,现在我们来讨 ...

  7. mysql的分区技术(建立分区)

    -- mysql建立表分区,使用range方法建立: create table t_range( id int(11), money int(11) unsigned not null, date d ...

  8. SQL的update from 理解

    学习了sql的语句都有快3年,工作上使用都一年半的,最近突然想起update from语句,感觉好像很模糊,虽然语法上使用一直正确,一直都是这样使用,但是就好像不是很明白里面的深处意思. 今天特意测试 ...

  9. c编程:提示用户输入一个0—9的数字进行猜测电脑产生的随机数。一共有三次机会。

    // //  main.c //  使用c语言进行编程: 题目:由电脑生成一个由0-9之间的随机数,提示用户也输入一个数字进行猜测.当猜测三次仍不中的时候结束程序. 编译环境:Xcode6.3 特别介 ...

  10. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...