HDU

来源:互联网 发布:手机淘宝店店招 编辑:程序博客网 时间:2024/06/07 07:22

ans = kkkk.点击打


点击打开链接

思路:


很不错的一个题目,知道求出k之后欧拉降幂递归可求,但是仍然无法再符合条件的时间内求出k,化简了一些式子. 根据欧拉函数的性质可以分成i和n互质不互质两种情况,然后就不会了...

对于n的质因数,考虑n无平方因子(square-free) ,所以存在gcd(n,n/p)==1.由欧拉函数性质 φ(ab)=φ(a)*φ(b)


解释一下 φ(i*n*p) p是n的质因子,那么有: φ(i*n*p)= φ(i*n)*p (由欧拉筛性质可得).

我们将i分为两种情况,一种是i和n互质,也就是上面第一种,然后是不互质,就是第二种.主要考虑第二种吧,如果不互质,那么

该数一定可以化成 k*p,我们上面就是枚举这个k,这样每次最多有m/p,这样复杂度下降是log级别的.φ(p)+1 和后面那

展开,因为n和i都有p,所以n再拿出一个p,这是i*p 正好是前面缺少的那部分i,两者提公因式.


这题目T了好多发,一直再实验,这里写了两种预处理了n所有的质因子m和直接枚举素数判断是否为质因子,预处理快了一

倍多.


另外,采用递归求的话需要预处理出当n为1的时候的欧拉函数的前缀和,而且根据上面的式子找到一个n的素因子即可.

递归求无限k就不多说了很简单

具体见代码.


#include<bits/stdc++.h>using namespace std;const int maxn = 1e7 + 10;typedef long long ll;const ll Mod = 1e9 + 7;int n,m,p;bool vis[maxn];int prime[maxn],phi[maxn];ll sum[maxn];int vt[maxn];int num,cnt;void init(){phi[1] = 1; cnt = 0;for(int i = 2;i < maxn;i++){if(!vis[i]){prime[cnt++] = i;phi[i] = i - 1;}for(int j = 0;j < cnt && (ll)prime[j] * i < maxn;j++){vis[i*prime[j]] = true;if(i % prime[j] == 0){phi[i*prime[j]] = phi[i] * prime[j];break;}elsephi[i*prime[j]] = phi[i] * (prime[j] - 1);}}sum[0] = 0;for(int i = 1;i < maxn ;i++)sum[i] = (sum[i - 1] + phi[i])%Mod;return ;}void yinzi(){num = 0;int res = n;for(ll i = 2; i * i <= res;i++){if(res % i == 0 && !vis[i]){vt[num++] = i;while(res % i == 0)res /= i;}}if(res > 1 && !vis[res])vt[num++] = res;return ;}ll solve(int n,int m){if(!n || !m) return 0;if(n == 1) return sum[m];if(m == 1)   return phi[n];/*for(int i = 0; i < cnt ;i++){int w = prime[i];if(w > n)continue;if(n % prime[i] == 0) {  return ((w - 1)*solve(n/w,m)%Mod+solve(n,m/w))%Mod; }}*/for(int i = 0;i < num;i++){int w = vt[i];if(n % w == 0)return (phi[w]*solve(n/w,m)%Mod+solve(n,m/w))%Mod;}return 0;}ll qmod(ll x,ll y,ll mod)  {      ll res=1;      x %= mod;    while(y)      {          if(y&1)          res=res*x%mod;          x=x*x%mod;          y>>=1;      }      return res%mod;  } ll cal(ll k,int x){if(x == 1) return 0;ll tmp = cal(k,phi[x]);return qmod(k,tmp+phi[x],x);}int main(){init();while(~scanf("%d %d %d",&n,&m,&p)){yinzi();ll k = solve(n,m);ll ans = cal(k,p);printf("%lld\n",ans);}}


#include<bits/stdc++.h>using namespace std;const int maxn = 1e7 + 10;typedef long long ll;const ll Mod = 1e9 + 7;int n,m,p;int prime[maxn],phi[maxn];ll sum[maxn];int vt[maxn];int num,cnt;void init(){phi[1] = 1; cnt = 0;for(int i = 2;i < maxn;i++){if(phi[i] == 0){prime[cnt++] = i;phi[i] = i - 1;}for(int j = 0;j < cnt && (ll)prime[j] * i < maxn;j++){if(i % prime[j] == 0){phi[i*prime[j]] = phi[i] * prime[j];break;}elsephi[i*prime[j]] = phi[i] * (prime[j] - 1);}}sum[0] = 0;for(int i = 1;i < maxn ;i++)sum[i] = (sum[i - 1] + phi[i])%Mod;return ;}ll solve(int n,int m){if(!n || !m) return 0;if(n == 1) return sum[m];if(m == 1)   return phi[n];for(int i = 0; i < cnt ;i++){int w = prime[i];if(w > n)continue;if(n % prime[i] == 0) {  return ((w - 1)*solve(n/w,m)%Mod+solve(n,m/w))%Mod; }}return 0;}ll qmod(ll x,ll y,ll mod)  {      ll res=1;      x %= mod;    while(y)      {          if(y&1)          res=res*x%mod;          x=x*x%mod;          y>>=1;      }      return res%mod;  } ll cal(ll k,int x){if(x == 1) return 0;ll tmp = cal(k,phi[x]);return qmod(k,tmp+phi[x],x);}int main(){init();while(~scanf("%d %d %d",&n,&m,&p)){ll k = solve(n,m);ll ans = cal(k,p);printf("%lld\n",ans);}}


f(n,m)=i=1mϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+i=1mpϕ(i×p×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+pi=1mpϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+(ϕ(p)+1)i=1mpϕ(i×n)=ϕ(p)i=1mϕ(i×np)+i=1mpϕ(i×n)=ϕ(p)f(np,m)+f(n,mp)f(n,m)=i=1mϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+i=1mpϕ(i×p×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+pi=1mpϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+(ϕ(p)+1)i=1mpϕ(i×n)=ϕ(p)i=1mϕ(i×np)+i=1mpϕ(i×n)=ϕ(p)f(np,m)+f(n,mp)f(n,m)=i=1mϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+i=1mpϕ(i×p×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+pi=1mpϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+(ϕ(p)+1)i=1mpϕ(i×n)=ϕ(p)i=1mϕ(i×np)+i=1mpϕ(i×n)=ϕ(p)f(np,m)+f(n,mp)f(n,m)=i=1mϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+i=1mpϕ(i×p×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+pi=1mpϕ(i×n)=ϕ(p)i=1&&i%p0mϕ(i×np)+(ϕ(p)+1)i=1mpϕ(i×n)=ϕ(p)i=1mϕ(i×np)+i=1mpϕ(i×n)=ϕ(p)f(np,m)+f(n,mp)

原创粉丝点击