hdu-5728 PowMod(数论)

题目链接:

PowMod

Time Limit: 3000/1500 MS (Java/Others)  

  Memory Limit: 262144/262144 K (Java/Others)


Problem Description
Declare:
k=mi=1φ(in) mod 1000000007

n is a square-free number.

φ is the Euler's totient function.

find:
ans=kkkk...k mod p

There are infinite number of k
 

 

Input
 
Multiple test cases(test cases 100), one line per case.

Each line contains three integers, n,m and p.

1n,m,p10^7
 

 

Output
 
For each case, output a single line with one integer, ans.
 

 

Sample Input
 
1 2 6
1 100 9
 

 

Sample Output
 
4
7
 
题意:
 
先算出那个k的值,再根据指数循环节算出答案;
 
思路:
 
这个博客给出了具体的推导过程,我就是参考这个的,而且代码也是;
 
AC代码;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>

using namespace std;

#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));

typedef  long long LL;

template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + '0');
    putchar('\n');
}

const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=1e7+10;
const int maxn=500+10;
const double eps=1e-8;

int phi[N],vis[N],prime[N],cnt;
LL sum[N],a[100];
inline void Init()
{
	cnt=0;
	sum[1]=1;
	phi[1]=1;
	For(i,2,N-1)
	{
		if(!vis[i])
		{
			for(int j=2*i;j<N;j+=i)
			{
				if(!vis[j])phi[j]=j;
				vis[j]=1;
				phi[j]=phi[j]/i*(i-1);
			}
			phi[i]=i-1;
			prime[++cnt]=i;
		}
		sum[i]=(sum[i-1]+phi[i])%mod;
	}
}

LL pow_mod(LL x,LL y,LL mo)
{
	LL s=1,base=x;
	while(y)
	{
		if(y&1)s=s*base%mo;
		base=base*base%mo;
		y>>=1;
	}
	return s;
}

LL work(LL a,LL b)
{
	if(b==1)return 0;
	LL sum=work(a,phi[b]);
	sum=sum+phi[b];
	LL ans=pow_mod(a,sum,b);
	return ans;
}

LL dfs(int pos,LL n,LL m)
{
	if(n==1)return sum[m];
	if(m==0)return 0;
	return ((a[pos]-1)*dfs(pos-1,n/a[pos],m)%mod+dfs(pos,n,m/a[pos]))%mod;
}

inline LL solve(LL n,LL m)
{
	int num=0;
	LL temp=n;
	if(!vis[n])a[++num]=n;
	else
	{
		for(int i=1;i<=cnt;i++)
		{
			if(n<prime[i])break;
			if(n%prime[i]==0)
			{
				a[++num]=prime[i];
				n/=prime[i];
			}
		}
	}
	return dfs(num,temp,m);
}

int main()
{
		Init();
		LL n,m,p;
        while(cin>>n>>m>>p)
		{
			LL k=solve(n,m);
			LL ans=work(k,p);
			print(ans);
		}

        return 0;
}

  

posted @ 2016-07-25 11:39  LittlePointer  阅读(672)  评论(0编辑  收藏  举报