JZOJ 5941. 乘
阿新 • • 發佈:2018-11-01
Sample Input
Sample Input1: 4 3 9 6 5 8 7 7
Sample Output
Sample Output1: 0
做法(轉自JZOJ):考慮 a 是定值, 而 b ≤ 1012 , 我們可以預處理 a 的 0...106 次方與 1 ∗ 106 , 2 ∗ 106 ...106 ∗ 106 次 方, 詢問時把 b 切成兩半, 拼起來就是答案. 這樣詢問就是 O(1) 的. 複雜度 O(q + 106 ).
1 #include <cstdio> 2View Code#include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <string> 6 #define LL long long 7 #define N 1000007 8 using namespace std; 9 LL a,p,q,k; 10 LL b,m,l,C,b1; 11 LL ans,mia[N],la[N]; 12 13 LL ksm(LL a,LL b){ 14 LL root=1,base=a; 15 while(b){16 if (b&1) root*=base,root%=p; 17 base*=base; 18 base%=p; 19 b>>=1; 20 } 21 return root; 22 } 23 24 25 int main(){ 26 freopen("pow.in","r",stdin); 27 freopen("pow.out","w",stdout); 28 scanf("%lld%lld%lld%lld",&a,&p,&q,&k);29 scanf("%lld%lld%lld%lld",&b,&l,&m,&C); 30 mia[0]=1; 31 la[0]=1; 32 LL g=1000000; 33 for(int i=1;i<=g;++i) 34 mia[i]=(mia[i-1]*a)%p,la[i]=ksm(mia[i],g)%p; 35 for(int i=1;i<=q;++i){ 36 b1=(b*m+C)%l; 37 ans=ans^((mia[b1%g]*la[b1/g])%p); 38 if (i%k==0) printf("%lld\n",ans); 39 b=b1; 40 } 41 }