Description
wy 和 wjk 是好朋友。
今天他们在一起聊天,突然聊到了以前一起唱过的《蒲公英的约定》。
“说到蒲公英,我给你讲一个故事吧。”
“嗯?”
“从前有两朵蒲公英,他们约定一起长大,在 N 天内每一天都长出同样多的种子,可是, 他们不想让其他植物知道他们到底要长出多少种子,于是他们中的哥哥想出了一个办法,最 开始,他会告诉弟弟一个数 P,然后在接下来的若干天里每一天哥哥会告诉弟弟两个数:a,c, 然后弟弟在这一天会干如下几件事情:
Step 1:首先把 c 和 lastans 按位异或得到 b,最开始 lastans 是 0
Step 2:如果这天的 b 等于 0,则说明他们已经长出了所有要长出的种子,哥哥与弟弟的交 流结束(输入文件也到此结束)
Step 3:如果这天的 b 不等于 0,弟弟会求出一个最小的非负整数 x 使得(即a^x同余于b模p),[题目保证可以找到这样的 x]
Step 4:lastans 赋值为 x
现在给你哥哥给弟弟的所有数字,你能求出每天弟弟要长出的种子的数量(即每天的 x)吗” “唔。。。”
今天他们在一起聊天,突然聊到了以前一起唱过的《蒲公英的约定》。
“说到蒲公英,我给你讲一个故事吧。”
“嗯?”
“从前有两朵蒲公英,他们约定一起长大,在 N 天内每一天都长出同样多的种子,可是, 他们不想让其他植物知道他们到底要长出多少种子,于是他们中的哥哥想出了一个办法,最 开始,他会告诉弟弟一个数 P,然后在接下来的若干天里每一天哥哥会告诉弟弟两个数:a,c, 然后弟弟在这一天会干如下几件事情:
Step 1:首先把 c 和 lastans 按位异或得到 b,最开始 lastans 是 0
Step 2:如果这天的 b 等于 0,则说明他们已经长出了所有要长出的种子,哥哥与弟弟的交 流结束(输入文件也到此结束)
Step 3:如果这天的 b 不等于 0,弟弟会求出一个最小的非负整数 x 使得(即a^x同余于b模p),[题目保证可以找到这样的 x]
Step 4:lastans 赋值为 x
现在给你哥哥给弟弟的所有数字,你能求出每天弟弟要长出的种子的数量(即每天的 x)吗” “唔。。。”
Input
第一行一个整数 P 接下来若干行(不妨认为有 N+1 行),每行两个整数 a,c,含义如题目描述所示。
Output
一共 N 行,每行一个整数,第 i 行代表第 i 天弟弟要长出的种子的数量(即第 i 天的 x 的值) [第 N+1 天弟弟会在第二步停止,所以不用求出这一天的 x 输出,只作为输入文件结束的标 志]
Sample Input
17
2 8
8 11
5 5
4 12
Sample Output
3
1
12
【样例解释】
[以下 N 行,每行两个整数,第一个整数代表第 i 天的 a,第二个整数代表第 i 天的 b]
2 8
8 8
5 4
4 0
Hint
【数据规模与约定】
对于 30%的数据 1 ≤ N ≤ 1000 1 ≤ P ≤ 1000
对于 60%的数据 1 ≤ N ≤ 10000 1 ≤ P ≤ 60000
另有 10%的数据 每一天的 a 都相等
对于 100%的数据 1 ≤ N ≤ 100000 1 ≤ P ≤ 100000 且 P 是素数 a,b ≤ P-1
对于 30%的数据 1 ≤ N ≤ 1000 1 ≤ P ≤ 1000
对于 60%的数据 1 ≤ N ≤ 10000 1 ≤ P ≤ 60000
另有 10%的数据 每一天的 a 都相等
对于 100%的数据 1 ≤ N ≤ 100000 1 ≤ P ≤ 100000 且 P 是素数 a,b ≤ P-1
法1:暴力模拟 30分
法2:BSGS求离散对数在O(P^½)可以回答询问,60分(我自然是不会的)
法3:我们知道最后一定会到0,所以我们可以倒着来模拟,式子我们就可以用快速幂来解决
code:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 inline long long ksm(long long a,long long b,long long mod){ 5 long long ans=1; 6 for(;b;b>>=1){ 7 if(b&1){ 8 ans*=a; 9 ans%=mod; 10 } 11 a*=a; 12 a%=mod; 13 } 14 return ans; 15 } 16 long long a[100005],c[100005],x[100005]; 17 inline long long read(){ 18 long long x=0,f=1; 19 char c=getchar(); 20 while(!isdigit(c)){ 21 if(c=='-')f=-1; 22 c=getchar(); 23 } 24 while(isdigit(c)){ 25 x=(x<<3)+(x<<1)+c-'0'; 26 c=getchar(); 27 } 28 return x*f; 29 } 30 int main(){ 31 // ios::sync_with_stdio(false); 32 long long P;P=read(); 33 long long cnt=0; 34 long long m,n; 35 while(scanf("%d%d",&m,&n)==2){ 36 a[++cnt]=m; 37 c[cnt]=n; 38 } 39 long long b=0; 40 x[cnt-1]=c[cnt]; 41 for(long long i=cnt-1;i>=1;i--){ 42 x[i-1]=ksm(a[i],x[i],P)^c[i]; 43 } 44 for(long long i=1;i<=cnt-1;i++){ 45 cout<<x[i]<<' '; 46 } 47 return 0; 48 }
我这道题被int给TLE了。。。?????
over