ssl1274.A 模拟+数学方法

题目

有一个正整数 a, 有 q 次询问, 每次给定一个正整数 bi , 求 a^bi 的值. 由于答案可能很大, 你只需要输出答案对 p 取模的结果。 又由于询问可能很多, 给定一个参数 k, 你只需要输出对于所有 k 的整数倍 i(0 < i ≤ q), 第一 次询问到第 i 次询问的结果的异或和. 为了防止输入文件过大, 每次询问的值以以下方法生成: 设 bi 为第 i 次询问的值, 给定 b0, l, m, c,i > 0 时,bi 满足 bi = (m ∗ bi−1 + c)mod l

数据规模如下
在这里插入图片描述

题解

直接模拟即可
对于 b i b_i bi可以直接一个一个求, O ( N ) O(N) ON时间可以接受
然后问题转化为如何快速求 a b a^b ab
可以预处理出 a a a的1~1000000次方,用 a b i ab_i abi存;然后在预处理出 a a a 100000 0 1 , 100000 0 2 . . . 100000 0 1000000 1000000^{1},1000000^{2}...1000000^{1000000} 1000000110000002...10000001000000次,用 b a i ba_i bai存。
对于 a b a^b ab,把b拆成两半(如 a 12345678 a^{12345678} a12345678拆成 a b [ 45678 ] ∗ b a [ 123 ] ab[45678]*ba[123] ab[45678]ba[123]),那么就可以O(1)求 a b a^b ab

代码

#include <cstdio>
#include <iostream>

using namespace std;

long long a,p,q,k,b0,l,m,c,b,ans;
long long ab[1000006],ba[1000006];

int main(){
	cin>>a>>p>>q>>k;
	cin>>b0>>l>>m>>c;
	ab[0]=1;
	for (int i=1;i<=1000000;i++)
		ab[i]=(ab[i-1]*a)%p;
	ba[0]=1;
	for (int i=1;i<=1000000;i++)
		ba[i]=(ba[i-1]*ab[1000000])%p;
	for (int i=1;i<=q;i++){
		b=(m*b0+c)%l;
		ans^=(ab[b%1000000]*ba[b/1000000])%p;
		b0=b;
		if (i%k==0&&i>=k) cout<<ans<<endl;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值