博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

bzoj:4407: 于神之怒加强版

Description

给下N,M,K.求
 
 

 

Input

输入有多组数据,输入数据的第一行两个正整数T,K,代表有T组数据,K的意义如上所示,下面第二行到第T+1行,每行为两个正整数N,M,其意义如上式所示。

 

Output

如题

 

Sample Input

1 2
3 3

Sample Output

20
 
 
感觉是道比较水的数论题?
提个d^k随手莫比乌斯反演一下,再把μ跟d^k放在一起,预处理出来就好了。
但是注意预处理的时候写nlogn写法的话会T,要放在线性筛里O(n)筛出来,30+s。
(玛雅,10+s是什么写法
 
#include<cstdio>
#include<algorithm>
#define N 5000000
using namespace std;

const int MOD=1e9+7;
int T,n,m,k,K,num=0,p[N],mu[N+1],ne,f[N+1],mmh;
bool bo[N+1];
inline int M(int x) {while (x>=MOD) x-=MOD;while (x<0) x+=MOD;return x;}
inline int mi(int a,int x){
    mmh=1;
    while (x){
        if (x&1) mmh=1LL*mmh*a%MOD;
        x>>=1;
        a=1LL*a*a%MOD;
    }
    return mmh;
}
inline int min(int a,int b){return a<b?a:b;}
int main(){
    register int i,j,k,l;
    scanf("%d%d",&T,&K);
    mu[1]=1;f[1]=1;
    for (i=2;i<=N;i++){
        if (!bo[i]) p[++num]=i,mu[i]=-1,f[i]=mi(i,K)-1;
        for (j=1;j<=num&&(ne=p[j]*i)<=N;j++){
            bo[ne]=1;
            if (i%p[j]) mu[ne]=-mu[i],f[ne]=1LL*f[i]*f[p[j]]%MOD;else{
                mu[ne]=0;
                f[ne]=1LL*f[i]*mi(p[j],K)%MOD;
                break;
            }
        }
    }
    for (i=1;i<=N;i++) f[i]=M(f[i]+f[i-1]);
    while(T--){
        scanf("%d%d",&n,&m);
        if (n>m) swap(n,m);
        for (i=1,j=0,mmh=0;i<=n;j=i++) i=min(n/(n/i),m/(m/i)),mmh=M(mmh+1LL*(n/i)*(m/i)%MOD*M(f[i]-f[j])%MOD);
        printf("%d\n",mmh);
    }
}
64280 kb 31400 ms C++/Edit 1092 B

 

posted @ 2016-05-22 09:43  swm_sxt  阅读(342)  评论(0编辑  收藏  举报