Power Sum
Time Limit: 20000/10000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)
SubmitStatus
Problem Description
给出n,m,p,求 (1^m + 2^m + 3^m + 4^m + ... + n^m) % p
Input
第一行一个数T( <= 10),表示数据总数
然后每行给出3个数n,m,p(1 <= n <= m <= 10^18, 1 <= p <= 10^6, p是质数
Output
每组数据输出你求得的结果
Sample Input
2 1 1 11 3 2 11
Sample Output
1 3
Hint
i^m即求 i * i * i * i * i... * i(m个i),比如2^3即2 * 2 * 2
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <math.h> 5 #include <algorithm> 6 using namespace std; 7 #define ll long long 8 int fac[100],fn,pri[1100],pn=0; 9 void init() 10 { 11 int i,j; 12 for(i=2;i<1100;i++) 13 { 14 if(!pri[i]) 15 { 16 pri[pn++]=i; 17 j=i*i; 18 while(j<1100) 19 { 20 pri[j]=1; 21 j+=i; 22 } 23 } 24 } 25 } 26 void findfac(int x) 27 { 28 fn=0; 29 int i,j; 30 for(i=0;x>=pri[i]&&i<pn;i++) 31 { 32 if(x%pri[i]==0) 33 { 34 fac[fn++]=pri[i]; 35 while(x%pri[i]==0)x/=pri[i]; 36 } 37 } 38 if(x!=1)fac[fn++]=x; 39 } 40 ll power(ll x,ll y,ll mod) 41 { 42 ll ans=1; 43 while(y) 44 { 45 if(y&1) 46 { 47 ans*=x; 48 ans%=mod; 49 } 50 x*=x; 51 x%=mod; 52 y>>=1; 53 } 54 return ans; 55 } 56 bool check(ll x,ll y) 57 { 58 ll z=y-1; 59 for(ll i=0;i<fn;i++) 60 if(power(x,z/fac[i],y)==1)return 0; 61 return 1; 62 } 63 int findroot(int x) 64 { 65 if(x==2)return 1; 66 findfac(x-1); 67 for(ll i=2;;i++) 68 if(check(i,x))return i; 69 } 70 int poww[1100000],repow[1100000]; 71 int dp[1100000]; 72 int main() 73 { 74 init(); 75 int t,root,i,j; 76 ll n,m,p; 77 scanf("%d",&t); 78 while(t--) 79 { 80 scanf("%lld%lld%lld",&n,&m,&p); 81 root=findroot(p); 82 m%=p-1; 83 int temp=1; 84 for(i=0;i<p;i++) 85 { 86 poww[i]=temp; 87 repow[temp]=i; 88 temp=temp*root%p; 89 } 90 dp[0]=0; 91 for(i=1;i<p;i++) 92 { 93 dp[i]=(dp[i-1]+poww[(repow[i]*m)%(p-1)])%p; 94 } 95 printf("%d\n",dp[n%p]); 96 } 97 }
Power Sum 竟然用原根来求
时间: 2024-10-05 19:48:59