Problem E: [Sdoi2013]项链
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 427 Solved: 146
[Submit][Status][Discuss]
Description
项链是人体的装饰品之一,是最早出现的首饰。项链除了具有装饰功能之外,有些项 链还具有特殊显示作用,如天主教徒的十字架
链和佛教徒的念珠。 从古至今人们为了美化人体本身,也美 化环境,制造了各种不同风格,不同特点、不同式样的项链,满足了不同肤色、不同民族、不同审美观的人的审美需要。就材料而论,首
饰市场上的项链有黄金、白银、珠宝等几种。珍珠项链为珍珠制成的饰品,即将珍珠 钻孔后用线串在一起,佩戴于项间。天然珍珠项链具有一定的护养作用。
最近,铭铭迷恋上了一种项链。与其他珍珠项链基本上相同,不过这种项链的珠子却 与众不同,是正三菱柱的泰山石雕刻而成的。三菱柱的侧面是正方形构成的,上面刻有数字。 能够让铭铭满意的项链必须满足下面的条件:
1:这串项链由n颗珠子构成的。
2:每一个珠子上面的数字x,必须满足0<x<=a,且珠子上面的数字的最大公约数要恰 好为1。两个珠子被认为是相同的,当且仅当他们经过旋转,或者翻转后能够变成一样的。 3:相邻的两个珠子必须不同。
4:两串项链如果能够经过旋转变成一样的,那么这两串项链就是相同的! 铭铭很好奇如果给定n和a,能够找到多少不同串项链。由于答案可能很大,所以对输 出的答案mod 1000000007。
Input
数据由多组数据构成:
第一行给定一个T<=10,代表由T组数据。
接下来T行,每行两个数n和a。
Output
对于每组数据输出有多少不同的串。
Sample Input
1
2 2
2 2
Sample Output
3
HINT
对于100%的数据:所有的n<=10^14,a<=10^7,T<=10;
题解:JSOI2012 爱之项链升级版,请先做JSOI2012 爱之项链;
推荐博客:http://m.blog.csdn.net/article/details?id=50688526
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #define ll long long 7 using namespace std; 8 const int p=1e9+7,N=10000005; 9 int tot,pri[N],mu[N],phi[N]; 10 bool vis[N]; ll a; 11 ll mod,t1,t3; 12 long double t2; 13 struct P{ 14 ll x; 15 P(){} 16 P(ll _x):x(_x){} 17 }n,ans,m,s1,s2,temp,sum[N]; 18 P operator *(P x,P y){ 19 ll t1,t3; long double t2; 20 t1=x.x*y.x,t2=(long double)x.x*y.x/mod; t3=(ll)(t1-(ll)t2*mod)%mod; 21 return (P){(t3+mod)%mod}; 22 } 23 P operator +(P x,P y){return (P)((x.x+y.x)%mod);} 24 P operator -(P x,P y){return (P)(((x.x-y.x)%mod+mod)%mod);} 25 ll read() 26 { 27 ll x=0,f=1; char ch; 28 while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') f=-1; 29 while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); 30 return x*f; 31 } 32 /*P ksm(P x,ll k,ll mod) 33 { 34 P res; res.x=1; for (ll i=k; i; i>>=1,x=x*x) if (i&1) res=res*x; 35 return res; 36 }*/ 37 P ksm(P x,ll y,ll p){ 38 if (y==0) return (P)(1); 39 if (y==1) return (P)(x.x%p); 40 P d=ksm(x,y/2,p); 41 if (y&1) return d*d*x; 42 else return d*d; 43 } 44 ll phii(ll x){ 45 if (x<N) return phi[x]; 46 ll t=x; 47 for (int i=2;i<=sqrt(x);i++){ 48 if (x%i==0){ 49 t=t-t/i; 50 while (x%i==0) x/=i; 51 } 52 } 53 if (x>1) t=t-t/x; 54 return t; 55 } 56 P work(ll x) 57 { 58 P res; res.x=0; 59 res=ksm((P)(m.x-1),x,mod); 60 if (x&1) res=res+(P)(1-m.x); else res=res+(P)(m.x-1); 61 res.x=(res.x+mod)%mod; 62 res=res*(P)(phii(n.x/x)); 63 return res; 64 } 65 void prepare() 66 { 67 tot=0; memset(vis,0,sizeof(vis)); mu[1]=phi[1]=1; 68 for (int i=2;i<N;i++){ 69 if (!vis[i]){ 70 mu[i]=-1,phi[i]=i-1; 71 pri[++tot]=i; 72 } 73 for (int j=1;j<=tot;j++){ 74 if (1LL*i*pri[j]>=N) break; 75 vis[i*pri[j]]=1; 76 if (i%pri[j]==0){ 77 mu[i*pri[j]]=0,phi[i*pri[j]]=phi[i]*pri[j]; 78 break; 79 }else mu[i*pri[j]]=-mu[i],phi[i*pri[j]]=phi[i]*phi[pri[j]]; 80 } 81 } 82 for (int i=0;i<N;i++) sum[i].x=0; 83 for (int i=1;i<N;i++) sum[i].x=sum[i-1].x+mu[i]; 84 } 85 int main() 86 { 87 prepare(); 88 int T=read(); 89 while (T--) 90 { 91 n.x=read(); a=read(); ans.x=0; ans.x=m.x=s1.x=s2.x=0; 92 if (n.x%p==0) mod=1ll*p*p; else mod=p; 93 for (int j,i=1;i<=a;i=j+1){ 94 j=a/(a/i); 95 s1=s1+(P)(a/i)*(P)(a/i)*(P)(a/i)*(P)(sum[j]-sum[i-1]); 96 s2=s2+(P)(a/i)*(P)(a/i)*(P)(sum[j]-sum[i-1]); 97 } 98 m=(P)(s1+s2*(P)((ll)3)+(P)((ll)2))*ksm((P)(6),1ll*p*(p-1)-1,mod); 99 for (int i=1; 1ll*i*i<=n.x; i++) 100 { 101 if (n.x%i==0){ 102 ans=ans+work(i); 103 if (1ll*i*i!=n.x) ans=ans+work(n.x/i); 104 } 105 } 106 mod=p; 107 if (n.x%p==0) 108 { 109 ans.x/=p; temp=(P)(n.x/p); temp=ksm(temp,p-2,p); 110 ans=ans*temp; printf("%lld ",ans.x%p); 111 } 112 else 113 { 114 temp=(P)(n.x); temp=ksm(temp,p-2,p); 115 ans=ans*temp; printf("%lld ",ans.x%p); 116 } 117 } 118 return 0; 119 }