您的位置:首页 > 其它

2017.6.15 数字表格 思考记录

2017-06-15 07:37 387 查看
利用gcd相同数相乘,可以比较基础的化到


然后就是设T=ij,利用除法了

但这个西格玛在指数上,怎么办呢?

其实是不影响的,只要保证约数、倍数关系对好就行了



易错点:

1、大量取模逆元快速幂

2、m/i *n/i 要取模P-1、

3、赋初值为1

码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#include<cstring>
#define P 1000000007
#define N 1000005
#define ll long long
int su
,tot,mu
,T;
ll sum
,ny
,x,y,n,m,i,j,fny
,f
;
bool he
;
ll ksm(ll a,ll b)
{
ll daan=1;
while(b)
{
if(b%2==1)daan=(daan*a)%P;
b/=2;
a=(a*a)%P;
}
return daan;
}
void exgcd(ll a,ll b)
{
if(!b)
{
x=1;
y=0;
return;
}
exgcd(b,a%b);
ll t=y;
y=x-(a/b)*y;
x=t;
}
void eular()
{
ll i,j;
mu[1]=1;sum[1]=1;sum[0]=1;
for(i=2;i<=N-5;i++)
{sum[i]=1;
if(!he[i])
{
su[++tot]=i;
mu[i]=-1;
}
for(j=1;j<=tot&&su[j]*i<=N-5;j++)
{
he[i*su[j]]=1;
if(i%su[j]==0)
{
mu[su[j]*i]=0;
break;
} else mu[su[j]*i]=-mu[i];
}
}
//
for(i=1;i<=N-5;i++)
{
for(j=1;j*i<=N-5;j++)
{
if(mu[j]==1)
{
// cout<<sum[i*j]<<" ";
sum[i*j]=sum[i*j]*f[i]%P;
//cout<<sum[i]<<endl;
}
if(mu[j]==-1)
{
sum[i*j]=sum[i*j]*fny[i]%P;
}
}
}
//cout<<i<<" ";
//sum[0]=1;
for(i=1;i<=N-5;i++)
{
sum[i]=(sum[i]*sum[i-1])%P;
exgcd(sum[i],P);
ny[i]=x;
}//
//cout<<"p";
//for(i=1;i<=1000;i++)cout<<sum[i]<<" ";
}
ll work()
{
ll ans=1,lin=0,i;
for(i=1;i<=n;i=lin+1)
{
lin=min(n/(n/i),m/(m/i));
ans=ans*ksm(sum[lin]*ny[i-1]%P,(n/i)*(m/i)%(P-1))%P;
}
return ((ans+P)%P);
}
int main()
{
ny[0]=1;
fny[0]=1;

f[0]=0;
f[1]=1;fny[1]=1;
for(i=2;i<=N-5;i++)
{
f[i]=(f[i-1]+f[i-2])%P;
exgcd(f[i],P);

fny[i]=x;
}
// for(i=1;i<=100;i++)cout<<fny[i]<<" ";
eular();
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld",&n,&m);
if(n>m)swap(n,m);
printf("%lld\n",work());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: