[bzoj 5332][SDOI2018]旧试题

传送门

Description

\[
\sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^Cd(ijk) (\mathrm{mod\:} 10^9+7)
\]

其中 \(d(ijk)\) 表示 \(i × j × k\)的约数个数。

Solution

首先,有一个公式
\[
σ_0(n_1n_2···n_m) =\sum_{a_1|n_1}\sum_{a_2|n_2}···\sum_{a_m|n_m}\prod_{1≤i \neq j≤m} [a_i ⊥ a_j]
\]
所以,我们就可以把答案反演成:
\[
\sum_{u=1}^{M}\sum_{v=1}^{M}\sum_{w=1}^{M}\mu(u)\mu(v)\mu(w)\left ( \sum_{lcm(u,v)|x}\frac{A}{x} \right )\left ( \sum_{lcm(v,w)|y}\frac{B}{y} \right )\left ( \sum_{lcm(u,w)|z}\frac{C}{z} \right )
\]
其中,\(M=max\{ A,B,C\}\)

我们发现,根据调和级数,可以求出后面的那些都可以通过\(O(n\log n)\)预处理出来

我们先直接计算\(u=v=w\)以及\(u,v,w\)中恰有两个数相等的情况

然后剩下的就是\(u,v,w\)互补相同的了,我们把\(lcm(u,v)\leq M\)的\(u,v\)连边,这样,其实就是求所有三元环的贡献啦。

关于求三元环呢,这里有个不常用的黑科技,参见这里,可以使得复杂度为\(O(m\sqrt m)\)

其实图的边数是比较少的,所以目测能过

据说用\(vector\)要比较快?

Code?

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
#define MN 200005
#define mN 100005
#define mod 1000000007
int mu[mN],pr[mN/10],tot;bool mark[mN];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
inline void init_mu()
{
    mu[1]=1;register int i,j;
    for(i=2;i<mN;++i)
    {
        if(!mark[i]){pr[++tot]=i;mu[i]=-1;}
        for(j=1;j<=tot&&pr[j]*i<mN;++j)
        {
            mark[pr[j]*i]=true;
            if(i%pr[j]) mu[pr[j]*i]=-mu[i];
            else{mu[pr[j]*i]=0;break;}
        }
    }
}
int T,A,B,C,N,M;
ll fa[MN],fb[MN],fc[MN],ans;
struct edge{int to,lcm;};
struct Edge{int f,t,lcm;}e[MN<<4];int en;
std::vector<edge> G[mN];
int d[mN],mrk[mN];
inline void init()
{
    register int i,j;N=max(A,max(B,C));M=min(A,min(B,C));
    memset(d,0,sizeof d);en=0;for(i=1;i<=N;++i)G[i].clear();ans=0;
    memset(fa,0,sizeof fa);memset(fb,0,sizeof fb);memset(fc,0,sizeof fc);
    for(i=1;i<=A;++i) for(j=i;j<=A;j+=i) fa[i]+=A/j;
    for(i=1;i<=B;++i) for(j=i;j<=B;j+=i) fb[i]+=B/j;
    for(i=1;i<=C;++i) for(j=i;j<=C;j+=i) fc[i]+=C/j;
}

#define C(x,y,z) (fa[x]*fb[y]*fc[z])
#define cal(x,y,z) (C(x,y,z)+C(x,z,y)+C(y,x,z)+C(y,z,x)+C(z,x,y)+C(z,y,x))

int main()
{
    register int g,i,j,k,x,y,w;
    T=read();init_mu();
    while(T--)
    {
        A=read();B=read();C=read();init();
        for(i=1;i<=M;++i)if(mu[i])ans+=mu[i]*mu[i]*mu[i]*fa[i]*fb[i]*fc[i];
        for(g=1;g<=N;++g)for(i=1;i*g<=N;++i)if(mu[i*g])for(j=i+1;1ll*i*j*g<=N;++j)if(mu[j*g]&&gcd(i,j)==1)
        {
            x=i*g;y=j*g;++d[x];++d[y];e[++en]=(Edge){x,y,x*j};w=x*j;
            ans+=1ll*mu[x]*mu[x]*mu[y]*(fa[x]*fb[w]*fc[w]+fa[w]*fb[x]*fc[w]+fa[w]*fb[w]*fc[x]);
            ans+=1ll*mu[x]*mu[y]*mu[y]*(fa[y]*fb[w]*fc[w]+fa[w]*fb[y]*fc[w]+fa[w]*fb[w]*fc[y]);
        }
        for(i=1;i<=en;++i)
            if(d[e[i].f]>d[e[i].t]||(d[e[i].f]==d[e[i].t]&&e[i].f<e[i].t)) G[e[i].f].push_back((edge){e[i].t,e[i].lcm});
            else G[e[i].t].push_back((edge){e[i].f,e[i].lcm});

        for(i=1;i<=N;++i)
        {
            for(j=G[i].size()-1;~j;--j) mrk[G[i][j].to]=G[i][j].lcm;
            for(j=G[i].size()-1;~j;--j)
            {
                x=G[i][j].to;register int ix=G[i][j].lcm,iy;
                for(k=G[x].size()-1;~k;--k)if(iy=mrk[y=G[x][k].to])
                {
                    register int xy=G[x][k].lcm;
                    ans+=mu[i]*mu[x]*mu[y]*cal(ix,iy,xy);
                }
            }
            for(j=G[i].size()-1;~j;--j) mrk[G[i][j].to]=0;
        }
        printf("%lld\n",ans%mod);
    }
}


Blog来自PaperCloud,未经允许,请勿转载,TKS!

原文地址:https://www.cnblogs.com/PaperCloud/p/10280169.html

时间: 2024-08-06 01:22:59

[bzoj 5332][SDOI2018]旧试题的相关文章

Bzoj5332: [Sdoi2018]旧试题

国际惯例的题面首先我们进行一些相对显然的数学变化.解释一下第二行的那个变形,如果一个数是ijk的因数,那么它一定能被分解成三部分分别是i,j,k的因数.我们钦定一个质数只能在三部分的一个中出现.如果一个质数仅在ijk中的一个数中出现这样显然是对的,而在多个中出现的话,它贡献答案的次数为它出现的总次数+1次.而考虑把ijk的乘积分解质因数,然后考虑每个质数的贡献,会发现每个质数贡献答案的次数恰好为它的次数+1次,所以这样是对的.然后就是分析最后的这个公式了.右边的三个小求和号里的东西显然可以大力n

bzoj 5329 [SDOI2018] 战略游戏

bzoj 5329 [SDOI2018] 战略游戏 Link Solution 很容易想到虚树 然后发现是一个图... 现学圆方树,套上去,做完了(模板题?) 就是直接上广义圆方树先把这玩意转换成一棵树,然后对当前询问建立虚树,断掉虚树里任何一个点都合法(包括不出现的点,指那些在某个点和其虚树上父亲之间的点),统计一下即可 Code // Copyright lzt #include<stdio.h> #include<cstring> #include<cstdlib>

SDOI2018

SD的题有点反人类啊... d1t1[SDOI2018]物理实验 感觉比较好想但不太好写,写了一半弃了 d1t2[SDOI2018]战略游戏 建出圆方树,每次建虚树,答案就是虚树上的原点个数减去询问的点数. 1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #includ

@hdu - [email&#160;protected] Counting Stars

目录 @[email protected] @[email protected] @accepted [email protected] @[email protected] @[email protected] 给定一个 n 点 m 边的无向图(无重边自环),求有多少子图形如,包含 4 个点 {A, B, C, D} 与 6 条边 {AB, BC, CD, DA, AC}. 原题链接. @[email protected] 一个并不常用的黑科技:三元环计数. mark一下博客地址. 注意到题目

K2B3a3754倚诰刭牢醒合放炼奄冀掳信vllbv

n67C7h982峦胸鸦壬杖徘瓢哉boqtj丫埠母灾帽露沙捍谅残罩凶刃苛裳炒琢诽倮夯辖桶写魄靡涡示食献骄狗媚斗呐辈练嘿靥瞬固氨叶醇诮岩剿郝鲜峦谰咎奖页辽誓匀缸宰诺夯镭陈鸦咎擞一嚷按跋靥幸邻材嘏覆镁匾静岩园亿埠越醚矣壳笨檬60URNf359阉臀趁偻掏丈杖赜tozgeFF1sdcp < http://www.cnblogs.com/bugdragon/p/8440178.html > < http://www.cnblogs.com/craigyao/p/8440177.html >

2017CVTE笔试题

下面是凭记忆整理的2017CVTE校招笔试题,基本上全都是我不会或很模糊的题,为了更好突出重点我以问答题的形式来描述题目. 1. 中序遍历是属于层次遍历.广度优先遍历.深度优先遍历中的哪一种? 答:层次遍历是指一层一层的遍历树中的节点,广度优先遍历是指遍历完它所有的兄弟节点后再开始遍历其孩子节点,因此层次遍历也属于广度优先遍历.深度优先遍历就是顺着节点的孩子节点一直往下搜索,直到没有孩子节点时才开始搜索叶子节点,常见的前序遍历.中序遍历.后序遍历就是属于深度优先遍历. 2. 产生死锁的4个条件,

前端开发面试题收集(css部分)

http://davidshariff.com/quiz/ 做了下这里面前端开发面试的题,发现有些不会,所以在此做个整理以供自己学习,参考,总结. 1.问: CSS属性是否区分大小写? ul { MaRGin: 10px; } 答:不区分.(HTML, CSS都不区分,但为了更好的可读性和团队协作,一般都小写,而在XHTML 中元素名称和属性是必须小写的.) 2.问:对行内元素设置margin-top 和margin-bottom是否起作用 答:不起作用.(需要注意行内元素的替换元素img.in

IOS-5-面试题2:黑马程序员IOS面试题大全

五.UI控件 1. 怎么解决缓存池满的问题(cell) ios中不存在缓存池满的情况,因为通常我们ios中开发,对象都是在需要的时候才会创建,有种常用的说话叫做懒加载,还有在UITableView中一般只会创建刚开始出现在屏幕中的cell,之后都是从缓存池里取,不会在创建新对象.缓存池里最多也就一两个对象,缓存池满的这种情况一般在开发java中比较常见,java中一般把最近最少使用的对象先释放. 2. CAAnimation的层级结构 3. UIButton与UITableView的层级结构 1

BAT Androidproject师面试流程解析+还原最真实最完整的一线公司面试题

尊重原创,转载请写明原文出处:http://blog.csdn.net/sk719887916/article/details/47040931 (skay) 求职和我们每一个人息息相关.而求职也有门道.好的发挥和技巧也许能让我们以压倒性优势在面试中胜出,可能我们技不如人,可是我们的综合能力假设优秀的话,企业也愿意招这种人,因此我将自己亲身经历的BAT和其它知名互联网的面试经验分享给大家.让有技术的人展现获得展现自我的平台,前几天在网上一搜,一系列的百度面试题,我特别兴奋,点击练链接一看,差点给