【JZOJ5884】蒲公英的约定

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


analysis

  • 正解BSGS放屁

  • 易知倒数第二条式子的答案即为最后的 c c c

  • 于是我们可以从一个式子的答案得出该式子真正的 b b b,再推到前一个式子的答案


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define MAXN 100005
#define ll long long
#define fo(i,a,b) for (register ll i=a;i<=b;i++)
#define fd(i,a,b) for (register ll i=a;i>=b;i--)

using namespace std;

ll a[MAXN],b[MAXN],c[MAXN];
ll n,mod,lastans;
__attribute__((optimize("-O3")))
ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while (ch<'0' || '9'<ch)
    {
        if (ch=='-')f=-1;
        ch=getchar();   
    }
    while ('0'<=ch && ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
__attribute__((optimize("-O3")))
ll pow(ll x,ll y)
{
	ll z=1;
	while (y)
	{
		if (y&1)z=z*x%mod;
		x=x*x%mod,y/=2;
	}
	return z%mod;
}
__attribute__((optimize("-O3")))
int main()
{
	freopen("dandelion.in","r",stdin);
	freopen("dandelion.out","w",stdout);
	mod=read();
	ll x,y;
	while (scanf("%lld%lld",&x,&y)!=EOF)a[++n]=x,b[n]=y;
	lastans=b[n--];
	fd(i,n,1)
	{
		c[i]=lastans;
		lastans=pow(a[i],lastans)^b[i];
	}
	fo(i,1,n)printf("%lld\n",c[i]);
	return 0; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值