Description
Input
Output
Sample Input
Sample Input1:
4 3 9 6
5 8 7 7
Sample Input2:
见下发文件中的 ex_pow2.in/out.
Sample Output
Sample Output1:
0
Sample Output2:
Data Constraint
Solution
-
考虑 a a a 是定值,而 b ≤ 1 0 12 b ≤ 10^{12} b≤1012 ,
-
我们可以预处理 a a a 的 0...1 0 6 0...10^6 0...106 次方与 1 ∗ 1 0 6 , 2 ∗ 1 0 6 … 1 0 6 ∗ 1 0 6 1 ∗ 10^6\ ,\ 2 ∗ 10^6…10^6 ∗ 10^6 1∗106 , 2∗106…106∗106 次方,
-
询问时把 b b b 切成两半,拼起来就是答案,这样询问就是 O ( 1 ) O(1) O(1) 的.。
-
时间复杂度 O ( q + 1 0 6 ) O(q + 10^6) O(q+106) 。
Code
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1e6+5;
const LL lim=1e12;
int a,p,q,k,m,c,ans,tot,pos;
LL b,l;
int f[N],pre[N];
LL g[N];
void write(int x)
{
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline int ksm(int x,LL y)
{
int s=1;
while(y)
{
if(y&1) s=(LL)s*x%p;
x=(LL)x*x%p;
y>>=1;
}
return s;
}
int main()
{
freopen("pow.in","r",stdin);
freopen("pow.out","w",stdout);
scanf("%d%d%d%d",&a,&p,&q,&k);
if(!q) return 0;
scanf("%lld%lld%d%d",&b,&l,&m,&c);
g[tot=f[1]=1]=0;
int num=ksm(a,N);
for(LL i=N;i<lim;i+=N)
{
g[++tot]=i;
f[tot]=(LL)f[tot-1]*num%p;
}
for(int i=pre[0]=1;i<N;i++) pre[i]=(LL)pre[i-1]*a%p;
for(int i=k;i<=q;i+=k)
{
for(int j=k/4;j;j--)
{
b=(b*m+c)%l;
pos=b/N+1;
ans^=(LL)f[pos]*pre[b-g[pos]]%p;
b=(b*m+c)%l;
pos=b/N+1;
ans^=(LL)f[pos]*pre[b-g[pos]]%p;
b=(b*m+c)%l;
pos=b/N+1;
ans^=(LL)f[pos]*pre[b-g[pos]]%p;
b=(b*m+c)%l;
pos=b/N+1;
ans^=(LL)f[pos]*pre[b-g[pos]]%p;
}
for(int j=k%4;j;j--)
{
b=(b*m+c)%l;
pos=b/N+1;
ans^=(LL)f[pos]*pre[b-g[pos]]%p;
}
write(ans),putchar('\n');
}
return 0;
}