BZOJ 4407 于神之怒加强版

Posted on 2017-02-26 18:48  ziliuziliu  阅读(171)  评论(0编辑  收藏  举报

这题正常多了。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 5000050
#define mod 1000000007
using namespace std;
long long t,n,m,k,prime[maxn],tot=0,k1[maxn],k2[maxn],tab[maxn];
bool vis[maxn];
long long f_pow(long long x,long long y)
{
    long long base=x,ans=1;
    while (y)
    {
        if (y&1) ans=(ans*base)%mod;
        base=(base*base)%mod;
        y>>=1;
    }
    return ans;
}
void get_table()
{
    k1[1]=k2[1]=1;
    for (long long i=2;i<=maxn-50;i++)
    {
        if (!vis[i])
        {
            tab[i]=f_pow(i,k);
            k1[i]=(tab[i]+mod-1)%mod;k2[i]=1;
            prime[++tot]=i;
        }
        for (long long j=1;j<=tot && i*prime[j]<=maxn-50;j++)
        {
            vis[i*prime[j]]=true;
            if (i%prime[j])
            {
                k1[i*prime[j]]=(tab[prime[j]]+mod-1)%mod;
                k2[i*prime[j]]=k1[i]*k2[i]%mod;
                continue;
            }
            k1[i*prime[j]]=k1[i]*tab[prime[j]]%mod;
            k2[i*prime[j]]=k2[i];break;
        }
    }
    for (long long i=1;i<=maxn-50;i++) {k1[i]=(k1[i]*k2[i])%mod;k1[i]=(k1[i-1]+k1[i])%mod;}
}
int main()
{
    scanf("%lld%lld",&t,&k);get_table();
    for (long long i=1;i<=t;i++)
    {
        scanf("%lld%lld",&n,&m);
        if (n>m) swap(n,m);
        long long ans=0,l=1,r;
        while (l<=n)
        {
            r=min(n/(n/l),m/(m/l));
            ans=(ans+(n/l)*(m/l)%mod*((k1[r]-k1[l-1]+mod)%mod))%mod;
            l=r+1;
        }
        printf("%lld\n",ans);
    }
    return 0;
}