【JZOJ A组】蒲公英的约定

版权声明:转载者乖乖♂站好 https://blog.csdn.net/Eric1561759334/article/details/82860234

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)吗” “唔。。。”

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

Data Constraint
对于 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

思路
不妨令第 i 次的 a,b,c,x 分别为 ai , bi , ci , xi
[令 m^ n代表 m、n 按位异或]
注意到b(n+1) ,而b(n+1)=c(n+1)^X(n) ,于是我们可以算出 Xn=C(n+1) . 于是假设我们已经算出来 k x ,于是我们倒序递推就可以得到全部的 x。

代码

#include<iostream>
#include<cstdio>
using namespace std;
int n=1,p;
long long c[100010],b[100010],a[100010];
long long ksm(long long a,long long b)
{
	long long r=1;
	for (;b;b>>=1,a=a*a%p) if (b&1) r=r*a%p;
	return r;
}
int main()
{
	freopen("dandelion.in","r",stdin);
	freopen("dandelion.out","w",stdout);
	scanf("%d",&p);
	while (scanf("%lld",&a[n])!=EOF) scanf("%lld",&c[n]),n++;
	n--,b[n]=c[n];
	for (int i=n-1;i>=1;i--) b[i]=ksm(a[i],b[i+1])^c[i];
	for (int i=2;i<=n;i++) printf("%lld\n",b[i]);
}

猜你喜欢

转载自blog.csdn.net/Eric1561759334/article/details/82860234