BZOJ3202 [Sdoi2013]项链

Problem E: [Sdoi2013]项链

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 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


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\n",ans.x%p);
111         }
112         else
113         {
114             temp=(P)(n.x); temp=ksm(temp,p-2,p);
115             ans=ans*temp; printf("%lld\n",ans.x%p);
116         }
117     }
118     return 0;
119 }
View Code

 

posted @ 2016-10-12 15:06  ACist  阅读(276)  评论(0编辑  收藏  举报