题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70017#problem/H
题意:求满足1<=i<=j<=n且lcm(i,j)=n的pair<i,j>的数目
一开始我是这么想的:
既然lcm(i,j)=n,
那么n=x*i=y*j,且x和y一定互质。
若i和j固定了,那么x和y也固定了。
那么问题就转化成求n的约数中互质的pair的数目
由唯一分解定理,设n有p个质因数,每个质因数的幂是a[i]
设x包括了其中的m个质因子,那么这m个y中一定就没有了
然后用排列组合可以YY出一个奇怪的式子
但是这种方法实际上并不好用。。。。
因为每个质因数可以取1....a[i]个。。。
最后式子中还会a要求a[]的全排列之类的。。。【什么鬼
然后就很复杂啦
换种思路:由lcm(A,B)=M
因为M是A和B的公倍数,所以M的质因数是A和B的并集
设分解质因数之后:
A=x^a1+y^a2+z^a3+......
B=x^b1+y^b2+z^b3+......
M=x^c1+y^c2+z^c3+......
因为M是A和B的最小公倍数,
所以对每个质因数都会有max(ai , bi)=ci
比如设ci=2,那么就有以下几种情况:
ai=2 , bi=2 ai=2 , bi=1 ai=2 , bi=0
ai=1 , bi=2 ai=0 , bi=2
用这个性质就可以推出公式啦:
对于每一个质因子,可能的情况有2*ci+1种
而不同质因子又是相互独立事件,所以直接套乘法原理,得ans=(2*c1+1)*(2*c2+1)*......*(2*ci+1)
但是中间会有重复的情况(用iPad或草稿纸YY一下很容易看出来的),所以还要ans=(ans-1)/2+1
注意注意注意:::
因为n很大,所以要注意数据类型。特别是中间变量的数据类型
【被坑了2h QAQ】
1 #include <cstdlib> 2 #include <cctype> 3 #include <cstring> 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <vector> 8 #include <string> 9 #include <iostream> 10 #include <map> 11 #include <set> 12 #include <queue> 13 #include <stack> 14 #include <bitset> 15 #include <list> 16 #include <cassert> 17 #include <complex> 18 using namespace std; 19 #define rep(i,a,n) for (int i=a;i<n;i++) 20 #define per(i,a,n) for (int i=n-1;i>=a;i--) 21 #define all(x) (x).begin(),(x).end() 22 //#define fi first 23 #define se second 24 #define SZ(x) ((int)(x).size()) 25 #define TWO(x) (1<<(x)) 26 #define TWOL(x) (1ll<<(x)) 27 #define clr(a) memset(a,0,sizeof(a)) 28 #define POSIN(x,y) (0<=(x)&&(x)<n&&0<=(y)&&(y)<m) 29 typedef vector<int> VI; 30 typedef vector<string> VS; 31 typedef vector<double> VD; 32 typedef long long ll; 33 typedef long double LD; 34 typedef pair<int,int> PII; 35 typedef pair<ll,ll> PLL; 36 typedef vector<ll> VL; 37 typedef vector<PII> VPII; 38 typedef complex<double> CD; 39 const int inf=0x20202020; 40 const ll mod=1000000007; 41 const double eps=1e-9; 42 43 ll powmod(ll a,ll b) //return (a*b)%mod 44 {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} 45 ll powmod(ll a,ll b,ll mod) //return (a*b)%mod 46 {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} 47 ll gcd(ll a,ll b) //return gcd(a,b) 48 { return b?gcd(b,a%b):a;} 49 // head 50 51 namespace Factor { 52 const int N=1010000; 53 ll C,fac[10010],n,mut,a[1001000]; 54 int T,cnt,i,l,prime[N],p[N],psize,_cnt; 55 ll _e[100],_pr[100]; 56 vector<ll> d; 57 58 inline ll mul(ll a,ll b,ll p) { //return (a*b)%p 59 if (p<=1000000000) return a*b%p; 60 else if (p<=1000000000000ll) return (((a*(b>>20)%p)<<20)+(a*(b&((1<<20)-1))))%p; 61 else { 62 ll d=(ll)floor(a*(long double)b/p+0.5); 63 ll ret=(a*b-d*p)%p; 64 if (ret<0) ret+=p; 65 return ret; 66 } 67 } 68 69 void prime_table(){ //prime[1..tot]: prime[i]=ith prime 70 int i,j,tot,t1; 71 for (i=1;i<=psize;i++) p[i]=i; 72 for (i=2,tot=0;i<=psize;i++){ 73 if (p[i]==i) prime[++tot]=i; 74 for (j=1;j<=tot && (t1=prime[j]*i)<=psize;j++){ 75 p[t1]=prime[j]; 76 if (i%prime[j]==0) break; 77 } 78 } 79 } 80 81 void init(int ps) { //initial 82 psize=ps; 83 prime_table(); 84 } 85 86 ll powl(ll a,ll n,ll p) { //return (a^n)%p 87 ll ans=1; 88 for (;n;n>>=1) { 89 if (n&1) ans=mul(ans,a,p); 90 a=mul(a,a,p); 91 } 92 return ans; 93 } 94 95 bool witness(ll a,ll n) { 96 int t=0; 97 ll u=n-1; 98 for (;~u&1;u>>=1) t++; 99 ll x=powl(a,u,n),_x=0; 100 for (;t;t--) { 101 _x=mul(x,x,n); 102 if (_x==1 && x!=1 && x!=n-1) return 1; 103 x=_x; 104 } 105 return _x!=1; 106 } 107 108 bool miller(ll n) { 109 if (n<2) return 0; 110 if (n<=psize) return p[n]==n; 111 if (~n&1) return 0; 112 for (int j=0;j<=7;j++) if (witness(rand()%(n-1)+1,n)) return 0; 113 return 1; 114 } 115 116 ll gcd(ll a,ll b) { 117 ll ret=1; 118 while (a!=0) { 119 if ((~a&1) && (~b&1)) ret<<=1,a>>=1,b>>=1; 120 else if (~a&1) a>>=1; else if (~b&1) b>>=1; 121 else { 122 if (a<b) swap(a,b); 123 a-=b; 124 } 125 } 126 return ret*b; 127 } 128 129 ll rho(ll n) { 130 for (;;) { 131 ll X=rand()%n,Y,Z,T=1,*lY=a,*lX=lY; 132 int tmp=20; 133 C=rand()%10+3; 134 X=mul(X,X,n)+C;*(lY++)=X;lX++; 135 Y=mul(X,X,n)+C;*(lY++)=Y; 136 for(;X!=Y;) { 137 ll t=X-Y+n; 138 Z=mul(T,t,n); 139 if(Z==0) return gcd(T,n); 140 tmp--; 141 if (tmp==0) { 142 tmp=20; 143 Z=gcd(Z,n); 144 if (Z!=1 && Z!=n) return Z; 145 } 146 T=Z; 147 Y=*(lY++)=mul(Y,Y,n)+C; 148 Y=*(lY++)=mul(Y,Y,n)+C; 149 X=*(lX++); 150 } 151 } 152 } 153 154 void _factor(ll n) { 155 for (int i=0;i<cnt;i++) { 156 if (n%fac[i]==0) n/=fac[i],fac[cnt++]=fac[i];} 157 if (n<=psize) { 158 for (;n!=1;n/=p[n]) fac[cnt++]=p[n]; 159 return; 160 } 161 if (miller(n)) fac[cnt++]=n; 162 else { 163 ll x=rho(n); 164 _factor(x);_factor(n/x); 165 } 166 } 167 168 void dfs(ll x,int dep) { 169 if (dep==_cnt) d.push_back(x); 170 else { 171 dfs(x,dep+1); 172 for (int i=1;i<=_e[dep];i++) dfs(x*=_pr[dep],dep+1); 173 } 174 } 175 176 void norm() { 177 sort(fac,fac+cnt); 178 _cnt=0; 179 rep(i,0,cnt) if (i==0||fac[i]!=fac[i-1]) _pr[_cnt]=fac[i],_e[_cnt++]=1; 180 else _e[_cnt-1]++; 181 } 182 183 vector<ll> getd() { 184 d.clear(); 185 dfs(1,0); 186 return d; 187 } 188 189 vector<ll> factor(ll n) { //return all factors of n cnt:the number of factors 190 cnt=0; 191 _factor(n); 192 norm(); 193 return getd(); 194 } 195 196 vector<PLL> factorG(ll n) { 197 cnt=0; 198 _factor(n); 199 norm(); 200 vector<PLL> d; 201 rep(i,0,_cnt) d.push_back(make_pair(_pr[i],_e[i])); 202 return d; 203 } 204 205 bool is_primitive(ll a,ll p) { 206 assert(miller(p)); 207 vector<PLL> D=factorG(p-1); 208 rep(i,0,SZ(D)) if (powmod(a,(p-1)/D[i].first,p)==1) return 0; 209 return 1; 210 } 211 } 212 213 int TTT; 214 ll N; 215 int main() 216 { 217 scanf("%d",&TTT); 218 Factor::init(200000); 219 //Factor::init(10000000); 220 for (int TT=1;TT<=TTT;TT++) 221 { 222 cin>>N; 223 //scanf("%lld",&N); 224 ll ans=1; 225 vector<PLL> p=Factor::factorG(N); 226 for (vector<PLL>::iterator i=p.begin();i!=p.end();i++) 227 { 228 ll tm=i->first; 229 int POW=0; 230 ll T=N; 231 while (T%tm==0) 232 { 233 POW++; 234 T=T/tm; 235 } 236 //cout<<"--> "<<tm<<" - "<<POW<<endl; 237 ans=ans*(1+2*POW); 238 } 239 ans=(ans-1)/2+1; 240 cout<<"Case "<<TT<<": "<<ans<<endl; 241 //printf("Case %d: %lld ",TT,ans); 242 //printf("Case %d: %lld ",TT,ans); 243 } 244 }