第一题求的是有多少正整数对 (i,j) (1<=i,j<=n) 且 (i,j)满足lcm(i,j)=n ,n <=10^14
解决方法 质因数分解,求出每个质因数的指数,c1,c2,c3..... cm ans=(c1*2+1)*(c2*2+1)....(cm*2+1)+1,ans/=2;
第二题求的是所有正整数对的和,n很大很大,最后结果取模。
解决方法 设质因数依次为 p1,p2,p3,p4..... pm 指数相应为 a1,a2,a3......an 对于每个质因数 求出 si=pi^0+pi^1+pi^2+
....+pi^ai ,si=(pi^(ai+1)-1)/(pi-1);题目中mod = 1000000007 为质数 可以利用这点直接利用二分幂函数 cal(x,p)
取逆 令 ti=si+ai*cal(pi,ai), 连乘 所有ti 得到 R ans=(R*2+n*2)/2
Light Oj 1236
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<iostream>
#include<string>
#include<sstream>
#include<cctype>
#include<set>
#include<stack>
#include<memory>
#include<deque>
#include<list>
#include<cmath>
#include<fstream>
#include<cstdlib>
#include<climits>
#include<iomanip>
#include<cstring>
#include<memory>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
template<class T> T gcd(T a,T b){ return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){ return a/gcd(a,b)*b;}
bitset<10000044>a;
ll p[800000];
int k;
void init()
{
a.reset();
int i,j;
a[0]=a[1]=1;
for(i=2;i*i<=10000000;i++)
{
if(!a[i])
{
for(j=i*i;j<=10000000;j+=i) a[j]=1;
}
}
k=0;
for(i=2;i<=10000000;i++) if(!a[i]) p[k++]=i;
}
int size;
ll f[12000];
ll c[12000];
ll cal(int n)
{
ll t=1;
for(int i=0;i<n;i++)
{
t*=(2*c[i]+1);
}
return (t+1)/2;
}
ll fact(ll n)
{
int i;
size=0;
memset(c,0,sizeof(c));
for(i=0;i<k&&p[i]*p[i]<=n;i++)
{
if(n%p[i]==0)
{
f[size]=p[i];
while(n%p[i]==0) n/=p[i],c[size]++;
size++;
}
}
if(n>1)
{
f[size]=n;
c[size]++;
size++;
}
return cal(size);
}
int main()
{
init();
int T,ca;
scanf("%d",&T);
for(ca=1;ca<=T;ca++)
{
ll n;
scanf("%lld",&n);
printf("Case %d: %lld\n",ca,fact(n));
}
return 0;
}
UVA Live Archive 6153
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<iostream>
#include<string>
#include<sstream>
#include<cctype>
#include<set>
#include<stack>
#include<memory>
#include<deque>
#include<list>
#include<cmath>
#include<fstream>
#include<cstdlib>
#include<climits>
#include<iomanip>
#include<cstring>
#include<memory>
#include<bitset>
#include<algorithm>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
template<class T> T gcd(T a,T b){ return b?gcd(b,a%b):a;}
template<class T> T lcm(T a,T b){ return a/gcd(a,b)*b;}
ll cal(int a,int b)
{
ll res=1,t=a;
while(b)
{
if(b&1) res=t*res%mod;
t=t*t%mod;
b>>=1;
}
return res;
}
ll get(int p,int a)
{
ll t=cal(p,a+1);
t=(t-1+mod)%mod;
ll r=cal(p-1,mod-2);
return t*r%mod;
}
ll go(const vector<int>&p,const vector<int>& a)
{
int size=p.size();
int i;
ll x,r,t,ans=1,k;
x=1;
for(i=0;i<size;++i)
{
t=get(p[i],a[i]);
k=cal(p[i],a[i]);
k=k*a[i]%mod;
t=(t+k)%mod;
x=(x*t)%mod;
}
ans=x*2%mod;
t=1;
for(t=1,i=0;i<size;++i)
t*=cal(p[i],a[i]),t%=mod;
ans=(ans+t*2)%mod;
r=cal(2,mod-2);
ans=(ans*r)%mod;
return ans;
}
int main()
{
int T,ca;
scanf("%d",&T);
for(ca=1;ca<=T;ca++)
{
int n;
cin>>n;
vector<int>p(n);
vector<int>a(n);
for(int i=0;i<n;++i)
{
scanf("%d%d",&p[i],&a[i]);
}
printf("Case %d: %lld\n",ca,go(p,a));
}
return 0;
}