DZY Loves Math [Bzoj 3309]

来源:互联网 发布:腾讯网络加速小助手 编辑:程序博客网 时间:2024/05/20 23:55

题目地址请点击——


DZY Loves Math


Description

对于正整数 n,定义 f(n)n 所含质因子的最大幂指数。
例如 f(1960)=f(235172)=3 , f(10007)=1 , f(1)=0
给定正整数 a , b,求 ai=1bj=1f(gcd(i,j))


Input

第一行一个数 T,表示询问数。
接下来 T 行,每行两个数 a,b,表示一个询问。


Output

对于每一个询问,输出一行一个非负整数作为回答。


Sample Input

4
7558588 9653114
6514903 4451211
7425644 1189442
6335198 4957


Sample Output

35793453939901
14225956593420
4332838845846
15400094813


Hint

T<=10000
1<=a,b<=107


Solution

nm

g(d) 表示 ni=1mj=1[gcd(i,j)=1]f(d),则

g(d)=d|pnpmpμ(pd)f(d)=i=1ndnidmidμ(i)f(d)

ans=i=1dg(d)=i=1nnimit|iμ(t)f(it)

F(i)=t|iμ(t)f(it),设 i 的唯一分解式为 pq11×pq22××pqss

要使 μ(t) 不为零,则

t=pm11×pm22××pmss , it=pq1m11×pq2m22××pqsmss

0mj1(1js)

Max(q1,q2,q3,,qs)=anumber(qj=a)=b

所以 f(it)=aa1

(1)f(it)=a

sum=ai=1b[Cibj=0sbCjsb(1)bi+j]=ai=1b[Cib(1)bij=0sbCjsb(1)j]

当且仅当 s=b 时,

sum=ai=1s[Cis(1)si]=a(i=0sCis(1)siC0s(1)s)=a(1)s

否则,sbj=0Cjsb(1)j=0,则 sum=0

(2)f(it)=a1

sum=(a1)j=0sbCjsb(1)b+j=(a1)(1)bj=0sbCjsb(1)j

当且仅当 s=b 时,

sum=(a1)(1)s

否则,sbj=0Cjsb(1)j=0,则 sum=0

综上,当 s=b 时,F(i)=(a1)(1)sa(1)s=(1)s+1,否则,F(i)=0

求出 F 的前缀和,然后分块优化即可。


Code

#include <iostream>#include <cstdio>#define LL long long#define MAXN 10000000#define Min(x,y) ((x)<(y)?(x):(y))using namespace std;LL T,n,m;bool no_prime[MAXN+10];LL prime[MAXN+10];LL sum[MAXN+10];LL g[MAXN+10];LL ci[MAXN+10];LL rci[MAXN+10];int main(){    sum[1]=0;    for(LL i=2;i<=MAXN;i++){        if(!no_prime[i]){prime[++prime[0]]=i;ci[i]=i;g[i]=1;rci[i]=1;}        for(LL j=1;prime[j]*i<=MAXN;j++){            no_prime[prime[j]*i]=true;            if(i%prime[j]==0){                rci[prime[j]*i]=rci[i]+1;                ci[prime[j]*i]=ci[i]*prime[j];                if(prime[j]*i/ci[prime[j]*i]==1)g[prime[j]*i]=1;                else if(rci[prime[j]*i]==rci[prime[j]*i/ci[prime[j]*i]])g[prime[j]*i]=g[prime[j]*i/ci[prime[j]*i]]*(-1);                break;             }            rci[prime[j]*i]=1;            ci[prime[j]*i]=prime[j];            if(prime[j]*i/ci[prime[j]*i]==1)g[prime[j]*i]=1;            else if(rci[prime[j]*i]==rci[prime[j]*i/ci[prime[j]*i]])g[prime[j]*i]=g[prime[j]*i/ci[prime[j]*i]]*(-1);        }        sum[i]=sum[i-1]+g[i];    }    scanf("%lld",&T);    while(T--){        LL ans=0;        scanf("%lld%lld",&n,&m);        if(n==0||m==0){            printf("0\n");            continue;        }        if(n>m)swap(n,m);        for(LL i=1,it;i<=n;i=it+1){            it=Min(n/(n/i),m/(m/i));            ans+=(sum[it]-sum[i-1])*(n/i)*(m/i);         }        printf("%lld\n",ans);    }    return 0;}
1 0
原创粉丝点击