题目
有一个正整数 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)
O(N)时间可以接受
然后问题转化为如何快速求
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}
10000001,10000002...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;
}
}