HDU 4746 Mophues 莫比乌斯第三弹

题意:1<=x<=n,1<=y<=m,使得gcd(x,y)=k,k的素因数个数小于等于p

例:24=2*2*2*3,k=4

解:设f[n]为gcd(a,b)=n的对数

F[d]为d|gcd(a,b)的对数

f[n]=sigema(mu[i],F[i*n]):

f[1]=mu[1]*F[1]+mu[2]*F[1*2]+...+mu[n]*F[1*n]

f[2]=mu[2]*F[2]+mu[2]*F[2*2]+...+mu[n]*F[2*n]

......

sum=f[1]+f[2]+...+f[n]=G[1]*F[1]+G[2]*F[2]+...+G[n]*F[n]

枚举每一个i,则i的倍数j为G[j]提供了mu[j/i]的贡献,即G[j]+=mu[j/i]

因为所求为k的素因数个数,所以将G[j]开成二维数组G[j][p]表示j对素因数个数为p的贡献

需要使用分块加速的方法,否则还是要爆炸

#include <stdio.h>
#include <string.h>
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)<(b)?(b):(a))
#define ll __int64
const int maxn=500005;
int num[maxn];
int prime[maxn];
int mu[maxn];
int factor[maxn];
int mbs[maxn][20];
void mobius()
{
    memset(num,0,sizeof(num));
    int all=0;
    mu[1]=1;
    factor[1]=0;
    for(int i=2;i<maxn;i++)
    {
        if(!num[i])
        {
            prime[all++]=i;
            mu[i]=-1;
            factor[i]=1;                 //记录素因数个数
        }
        for(int j=0;j<all&&i*prime[j]<maxn;j++)
        {
            num[i*prime[j]]=1;
            factor[i*prime[j]]=factor[i]+1;
            if(i%prime[j])
            {
                mu[i*prime[j]]=-mu[i];
            }
            else
            {
                mu[i*prime[j]]=0;
                break;
            }
        }
    }
    return ;
}
void inti()
{
    memset(mbs,0,sizeof(mbs));
    for(int i=1;i<maxn;i++)
        for(int j=i;j<maxn;j+=i)
            mbs[j][factor[i]]+=mu[j/i];        //每个j在factor[i]个素因数中的贡献
/*下面是为了分块加速求和*/
    for(int i=1;i<maxn;i++)
        for(int j=0;j<19;j++)
            mbs[i][j]+=mbs[i-1][j];
    for(int i=0;i<maxn;i++)
        for(int j=1;j<19;j++)
            mbs[i][j]+=mbs[i][j-1];
    return ;
}
int main()
{
    int t,n,m,p;
    mobius();
    inti();
    ll sum;
    while(scanf("%d",&t)!=-1)
    {
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&p);
            if(p>=19)                    //因为2^19>500000,所以超过了19就是全体均满足要求
            {
                printf("%I64d\n",(ll)n*m);
                continue;
            }
            if(n>m)
            {
                int te=n;
                n=m;
                m=te;
            }
            sum=0;
            for(int i=1,last;i<n;i=last+1)
            {
                last=MIN(n/(n/i),m/(m/i));           
//分块加速,因为[n/i][m/i]在i递加过程中具有重复部分,跳掉这些i可是简化计算,是复杂度降低至sqrt(n)
                sum+=((ll)(n/i)*(m/i)*(mbs[last][p]-mbs[i-1][p]));
            }
            printf("%I64d\n",sum);
        }
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-15 05:49:17

HDU 4746 Mophues 莫比乌斯第三弹的相关文章

HDU 4746 Mophues (莫比乌斯反演应用)

Mophues Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 327670/327670 K (Java/Others) Total Submission(s): 980    Accepted Submission(s): 376 Problem Description As we know, any positive integer C ( C >= 2 ) can be written as the multiply of

HDU 4746 Mophues 莫比乌斯反演

分析: http://blog.csdn.net/acdreamers/article/details/12871643 分析参见这一篇 http://wenku.baidu.com/view/fbe263d384254b35eefd34eb.html 分块看这一篇 #include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #i

【莫比乌斯】HDU 4746 Mophues

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4746 题意:定义f(x) = x分解质因数出来的因子个数,如 x = p0 * p0 * p0 * p1 * p2,则f(x) = 5,特殊的, f(1) = 0,求 i = [1..n], j = [1..m] 组成的n*m组(i, j)对中,有多少组f( gcd(i,j) ) <= p 思路: 代码: TAG:

HDU - 4746预处理莫比乌斯反演

链接 求[1,n] 和 [1,m]中有多少对数的GCD的素因子个数小于等于p 直接暴力做特定超时,所以我们想办法预处理,对于p大于18(1到5e5的最大素数因子个数)的情况,每一对都满足条件,O(1)得结果. p<=18时,预处理sum[i][j]sum[i][j]表示所有能整除i的质因子个数<=j的(x,y)的对数,然后求一个前缀和,ans=∑⌊n/d⌋∗⌊m/d⌋∗∑k|dμ(d/k) //#pragma comment(linker, "/stack:200000000&quo

日均百万PV架构第三弹(分布内容为王)

接续接上篇 缓存时代来临 为蓝本,继续改造我们的百万级站点架构,这次我们 拿之前存储静态内容的 nfs 开刀,众所周知 nfs 的多台集群节点下可能由于多重 原因(磁盘io , 网络带宽, 并发场景),不适合做文件共享系统的基础结构. 互联网站点中,存在大量图片或其他静态内容,并且这些内容一般在1M之内,对于 海量小文件,我们将采用mogilefs分布式文件系统来完成.其中概念自行google. # mogilefs分布式文件系统工作流程 架构已经愈发复杂,我们需要从新梳理一下.从下表中应该很容

《我与希乐仑》第三弹

此案编号:黄劳人仲 (2014) 办字 第518号 开庭前,发生了一个戏剧性的场景,对方来了三个人,一位是外服的李盼,一位是徐敏,但还有一位叫王霞的,尽然说是Selerant的HR,扯淡嘛!此人来审判庭的目的非常值得怀疑,首先我有充分的证据证明她不属于Selerant,很简单!我们可以去调阅她的人事档案,至少在2014年3月26日当天,她肯定不属于Selerant,因为我清楚地记得她是徐敏的朋友,所以罗,纯粹是打酱油的,也或许是来拉关系的.你说一个不相干的人,庭上基本没说话,那她来干什么?这又不

codechef营养题 第三弹

第三弾が始まる! codechef problems 第三弹 一.Motorbike Racing 题面 It's time for the annual exciting Motorbike Race in Byteland. There are N motorcyclists taking part in the competition. Johnny is watching the race. At the present moment (time 0), Johnny has taken

深究angularJS系列 - 第三弹

深究angularJS系列 - 初识 深究angularJS系列 - 第二弹 深究angularJS系列 - 第三弹,我们一起深入探究angular的服务和自定义指令O(∩_∩)O~~ Angular服务 $http: $http是angular中的一个核心服务; $http利用浏览器的xmlhttprequest或JSONP与远程HTTP服务器进行交互; $http的支持多种method的请求,get.post.put.delete.jsonp等. 下面通过JSONP方法进行$http服务的使

Android Window PhoneWindow Activity学习心得--第三弹

Android Window  PhoneWindow Activity学习心得--第三弹 前面 我们完成了从Activity到PhoneWindow的整体跨度 正如我们所知道的与Activity组件关联的一个应用程序窗口视图对象关联一个ViewRoot对象,而将 一个Activity组件的应用程序窗口视图对象与一个ViewRoot对象关联是通过该Activity组件所使用的 窗口管理器(WindowManager)来执行的. 在我们初始化DecorView完成之后,我们需要关联应用程序窗口视图