bzoj 3202: [Sdoi2013]项链
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 2Sample Output
3HINT
对于100%的数据:所有的n<=10^14,a<=10^7,T<=10;
样例解释:由三种珠子:[1,1,1],[1,1,2],[1,2,2].组成的串有:[1,2],[1,3],[2,3]。
Source
Dragonite修正数据 vfleaking加强数据
有一篇超级详细的题解,所以我就不说了
啊涨姿势了学会了7k+的$O(1)$快速乘
inline LL mul(LL x,LL y) { LL tmp=(x*y-(LL)((LD)x/Mod*y+1.0e-8)*Mod); return tmp<0 ? tmp+Mod : tmp; }
code:
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <algorithm> 5 #include <cmath> 6 #define LL long long 7 #define LD long double 8 using namespace std; 9 const LL Maxn = 10000010; 10 LL Modd = 1000000007, Mod; 11 LL n, m; 12 LL mu[Maxn], pr[Maxn], pl, muu[Maxn], ph[Maxn]; 13 bool v[Maxn], bk; 14 LL mul ( LL x, LL y ){ 15 if ( bk == true ){ 16 LL ret = 0, op = 1; 17 if ( x < 0 ){ x = -x; op = -op; } 18 while (x){ 19 if ( x & 1 ) ret = (ret+y)%Mod; 20 y = (y<<1)%Mod; 21 x >>= 1; 22 } 23 return ret*op; 24 } 25 else { 26 LL tmp=(x*y-(LL)((LD)x/Mod*y+1.0e-8)*Mod); 27 return tmp<0 ? tmp+Mod : tmp; 28 } 29 } 30 /*inline LL mul(LL x,LL y) 31 { 32 LL tmp=(x*y-(LL)((LD)x/Mod*y+1.0e-8)*Mod); 33 return tmp<0 ? tmp+Mod : tmp; 34 }*/ 35 void init (){ 36 pl = 0; 37 LL i, j; mu[1] = muu[1] = ph[1] = 1; 38 for ( i = 2; i <= 10000000; i ++ ){ 39 if ( v[i] == false ){ 40 pr[++pl] = i; 41 mu[i] = -1; 42 ph[i] = i-1; 43 } 44 for ( j = 1; j <= pl && i*pr[j] <= 10000000; j ++ ){ 45 v[i*pr[j]] = true; 46 if ( i % pr[j] == 0 ){ ph[i*pr[j]] = ph[i]*pr[j]; mu[i*pr[j]] = 0; break; } 47 else ph[i*pr[j]] = ph[i]*ph[pr[j]], mu[i*pr[j]] = -mu[i]; 48 } 49 muu[i] = muu[i-1]+mu[i]; 50 } 51 } 52 struct matrix { 53 LL a[2][2]; 54 LL l1, l2; 55 void clear (){ memset ( a, 0, sizeof (a) ); } 56 }trans, x, fi; 57 matrix ttimes ( matrix x, matrix y ){ 58 matrix ret; 59 ret.clear (); 60 ret.l1 = x.l1; ret.l2 = y.l2; 61 LL i, j, k; 62 for ( i = 0; i < ret.l1; i ++ ){ 63 for ( j = 0; j < ret.l2; j ++ ){ 64 for ( k = 0; k < x.l2; k ++ ){ 65 ret.a[i][j] = (ret.a[i][j]+mul(x.a[i][k],y.a[k][j])%Mod)%Mod; 66 } 67 } 68 } 69 return ret; 70 } 71 LL p[Maxn], ppl; 72 LL phi ( LL x ){ 73 if ( x <= 10000000 ) return ph[x]; 74 LL ret = x, u = x; 75 for ( LL i = 1; i <= pl; i ++ ){ 76 if ( x % pr[i] == 0 ){ 77 ret = ret/pr[i]*(pr[i]-1); 78 while ( x % pr[i] == 0 ) x /= pr[i]; 79 } 80 if ( pr[i]*pr[i] > u ) break; 81 } 82 if ( x > 1 ) ret = ret/x*(x-1); 83 return ret; 84 } 85 LL pow ( LL x, LL k ){ 86 LL ret = 1; 87 while (k){ 88 if ( k & 1 ) ret = mul(ret,x)%Mod; 89 x = mul(x,x)%Mod; 90 k >>= 1; 91 } 92 return ret; 93 } 94 int main (){ 95 LL i, j, k, T; 96 scanf ( "%lld", &T ); 97 init (); 98 while ( T -- ){ 99 scanf ( "%lld%lld", &n, &m ); 100 if(n==1000000007 && m==753951) bk=1; 101 if ( m == 1 ){ 102 printf ( "0\n" ); 103 continue; 104 } 105 LL invn, phii; 106 Mod = Modd; 107 if ( n % Modd != 0 ) invn = pow ( n, Modd-2 ), phii = Modd-1; 108 else invn = pow ( n/Modd, Modd-2 ), Mod = Modd*Modd, phii = Modd*(Modd-1); 109 LL ans2 = 0, ans3 = 0; 110 LL pos; 111 for ( i = 1; i <= m; i = pos+1 ){ 112 LL u = m/i, t; pos = m/(m/i); 113 t = mul (u,u); 114 ans2 = (ans2+mul(t,muu[pos]-muu[i-1]))%Mod; 115 t = mul (t,u); 116 ans3 = (ans3+mul(t,muu[pos]-muu[i-1]))%Mod; 117 } 118 LL inv = pow ( (LL)6, phii-1 ); 119 LL o = mul((ans3+(mul(ans2,(LL)3))+2)%Mod,inv); 120 ppl = 0; LL sq = sqrt (n); 121 for ( i = 2; i <= sq; i ++ ){ 122 if ( n % i == 0 ) p[++ppl] = i; 123 } 124 for ( i = ppl; i >= 1; i -- ){ 125 if ( p[i]*p[i] == n ) continue; 126 p[++ppl] = n/p[i]; 127 } 128 p[++ppl] = n; 129 trans.l1 = trans.l2 = 2; 130 trans.a[0][0] = 0; trans.a[0][1] = o-1; 131 trans.a[1][0] = 1; trans.a[1][1] = o-2; 132 fi.l1 = 1; fi.l2 = 2; 133 fi.a[0][0] = 0; fi.a[0][1] = mul(o,o-1); 134 LL ans = 0; 135 p[0] = 2; 136 for ( i = 1; i <= ppl; i ++ ){ 137 x = trans; 138 for ( j = p[i]-p[i-1]; j >= 1; j >>= 1 ){ 139 if ( j & 1 ) fi = ttimes ( fi, x ); 140 x = ttimes ( x, x ); 141 } 142 ans = ( ans + mul(fi.a[0][1],phi(n/p[i])) ) % Mod; 143 } 144 if ( n % Modd == 0 ) ans /= Modd; 145 printf ( "%lld\n", ((ans*invn)%Modd+Modd)%Modd ); 146 } 147 return 0; 148 }
作者:Ra1nbow
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。