[20191003机房测试] 太阳神

太阳神拉很喜欢最小公倍数,有一天他想到了一个关于最小公倍数的题目
求满足如下条件的数对(a,b)对数:
a,b 均为正整数且 a,b<=n 而lcm(a,b)>n
其中的 lcm 当然表示最小公倍数
答案对 1,000,000,007取模

数据范围是1e10的,打表找了半天规律发现没用……
那就莫比乌斯反演呗

题目求:

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[lcm(i,j)> n]\]

但是大于的太多了,那我们就反过来求,最后用总的来减

也就是求:

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[lcm(i,j)\leq n]\]

先把\(lcm\)拆开

\[\sum_{i=1}^{n}\sum_{j=1}^{n}[\dfrac{i·j}{gcd(i,j)}\leq n]\]

看到\(gcd\),枚举 \(i,j\) 的约数 \(d\)

\[\sum_{d=1}^{n}\sum_{i=1}^{n}\sum_{j=1}^{n}[\dfrac{i·j}{d}\leq n]\]

拉出去反演:

\[\sum_{d=1}^{n}\sum_{i'=1}^{\lfloor{\frac{n}{d}}\rfloor}\sum_{j'=1}^{\lfloor{\frac{n}{i'·d}}\rfloor}[gcd(i',j')=1]\]

引入莫比乌斯函数:

\[\sum_{d=1}^{n}\sum_{i'=1}^{\lfloor{\frac{n}{d}}\rfloor}\sum_{j'=1}^{\lfloor{\frac{n}{i'·d}}\rfloor}\mu(gcd(i',j'))\]

再枚举 \(i',j'\) 的约数 \(d'\),继续反演

\[\sum_{d=1}^{n}\sum_{d'=1}^{\sqrt{\frac{n}{d}}}\mu(d')\sum_{i''=1}\sum_{j''=1}\lfloor{\frac{n}{d·d'^2i''}}\rfloor\]

把\(d'\)拿出来:

\[\sum_{d'=1}^{\sqrt{n}}\mu(d')[d·i''·j''\leq \frac{n}{d'^2}\text{的组数}]\]

然后就是求满足\(d·i''·j''\leq \frac{n}{d'^2}\)的三元组(d,i‘‘,j‘‘)的个数

这个可以\(\Theta(n^{\frac{2}{3}})\)算出来

就可以了

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 100005
#define M 100000
#define mod 1000000007
using namespace std;

ll n,ans,siz,sum,maxn,x;
ll mu[N],prime[N],primenum;
bool isprime[N];

template<class T>inline void read(T &res)
{
    char c;T flag=1;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}

void init()
{
    mu[1]=1;
    for(register int i=2;i<=M;++i)
    {
        if(!isprime[i])
        {
            prime[++primenum]=i;
            mu[i]=-1;
        }
        for(register int j=1;j<=primenum;++j)
        {
            if(i*prime[j]>M) break;
            isprime[i*prime[j]]=1;
            if(!(i%prime[j]))
            {
                mu[i*prime[j]]=0;
                break;
            }
            mu[i*prime[j]]=-mu[i];
        }
    }
}

int main()
{
    freopen("ra.in","r",stdin);
    freopen("ra.out","w",stdout);
    read(n);
    init();
    siz=(ll)(sqrt(n)+0.5);
    for(register ll i=1;i<=siz;++i)
    {
        sum=0;
        maxn=n/i/i;
        for(register ll j=1;j*j*j<=maxn;++j)
        {
            for(register ll k=j;k*k<=maxn/j;++k)
            {
                x=(maxn/j/k-k+1);
                if(j==k) sum=(sum+1+(x-1)*3)%mod;
                else sum=(sum+3+(x-1)*6)%mod;
            }
        }
        sum%=mod;
        ans=(ans+mu[i]*sum)%mod;
    }
    ans=((n%mod)*(n%mod)-ans)%mod;
    while(ans<0) ans+=mod;
    printf("%lld\n",ans);
    return 0;
}
/*
10000000000
210705255
*/

原文地址:https://www.cnblogs.com/tqr06/p/11619827.html

时间: 2024-10-03 23:18:14

[20191003机房测试] 太阳神的相关文章

[CSP-S模拟测试]:太阳神(莫比乌斯反演)

题目描述 太阳神拉很喜欢最小公倍数,有一天他想到了一个关于最小公倍数的题目.求满足如下条件的数对$(a,b)$对数:$a,b$均为正整数且$a,b\leqslant n$而$lcm(a,b)>n$.其中的$lcm$当然表示最小公倍数.答案对$1,000,000,007$取模 输入格式 第一行一个正整数$n$. 输出格式 一行一个整数表示答案,对$1,000,000,007$取模. 样例 样例输入: 3 样例输出: 2 数据范围与提示 对于$20\%$的数据$n\leqslant 2,000$:对

[20191003机房测试] 天空龙

奥西里斯之天空龙很喜欢颜色,有一天他找到了三种颜色--红黄蓝 奥西里斯有 a 个红色,b 个黄色,c 个蓝色,他想画出最好的画, 可是需要至少 x 个红色,y 个黄色和 z 个蓝色,似乎并不够. 别担心,奥西里斯会魔法! 他可以把任何两个同种颜色转化为一个另一种颜色! 请问他能不能完成呢? 这题目描述让我感受到面对机翻的恐惧-- 这又不是外语翻译过来的啊喂!什么语文水平? 很显然,如果有多余的颜色,把它们分别÷2,就是可以转换的数量 然后再与差的颜色比较,得出答案 代码: #include<bi

csp-s模拟测试57(10.2)「天空龙」&#183;「巨神兵」&#183;「太阳神」

题目是古埃及神话??? A. 天空龙 傻逼模拟,看来没有滑天下之大稽QAQ,也没有打错快读(大雾...) B. 巨神兵 难度爆增,一脸懵比..... 60分状压: 因为是求有向图,关于有向图好像拓扑用的很多,考虑到每个图的拓扑序是一定的 那么我们可以借此转移,设f[i][j]为当前点的状态为i,出度为零的点的度数为j 向下一层转移时枚举下一层的点集,那么点集S中每个点一定要和j连边,可以和i中除j以外的点连边 然后对于每个点cnt1,表示除j以外与i的连边,cnt2表示与j的连边,该点的贡献为2

vs2008编译QT开源项目--太阳神三国杀源码分析(三) 皮肤

太阳神三国杀的界面很绚丽,界面上按钮的图标,鼠标移入移出时图标的变化,日志和聊天Widget的边框和半透明等效果,既可以通过代码来控制,也可以使用皮肤文件qss进行控制.下面我们分析一下三国杀的qss文件. 在main.cpp中可以看到如下几句关键代码: QDir::setCurrent(qApp->applicationDirPath());//设置当前目录为程序的可执行文件所在目录 //设置皮肤    QFile file("sanguosha.qss");    if(fi

机房测试3:太阳神 ra (莫比乌斯反演)

题目: 分析:(终于在yyr大佬的援助下弄懂了这道题...) 首先lcm>n的限制太少,不好直接处理,转换成求补集,也就是lcm<=n,最后用n^n-ans即可. 考虑怎么求lcm<=n: #include<bits/stdc++.h> using namespace std; #define ll long long #define N 100005 #define ri register int const ll mod=1e9+7; int mu[N],lim,pri[

Host1Plus主机商8个机房测试IP体验

Host1Plus商家也算是比较老的海外主机商(英国),当初进入中国市场也是比较早的,记得那时候支持支付宝的海外主机商尤其的深受用户喜欢.因为我 们大部分网友.站长最多有一个支付宝,很少有双币信用卡或者贝宝支付美元的能力.不过后来几年,HOST1PLUS商家逐渐的落寞,主要原因在于其他商家 的出现,以及他们本身营销能力和产品的策略. 尤其是提供的虚拟主机和VPS主机,价格和方案不是太符合中国用户的口味,配置比较低,而且机房较 少.不过商家应该意识到这一点,在最近2年改动挺大的,今天公司业务正好有

机房测试1:big(贪心+Trie树)

题目: 分析: 考虑最暴力的办法:枚举选哪个数,枚举对手在哪个时间变化,然后统计答案. 对于异或这一类问题,考虑区间异或可以抵消重复区间,维护一个前缀异或和:pre[i]表示1~i的异或和,suf[i]表示i~n的异或和. 将对手的式子化简,2*x即将x向左移一位,/( 2^n )为向右移n位,+2*x ,%2^n类似. 模拟一下:12345 -> 123450 -> 123451 -> 23451 每次枚举对手要变的时间i,最后的值即为:work ( pre[i] ^ x ) ^ su

[20191004机房测试] ZGY的早餐

ZGY 每天早上要从宿舍走路到机房,顺便从学校小卖部购买早饭,当然机智的 ZGY 一定会走最短路 学校的路可以看成一无向联通张图,图上有 n 个点,m 条边,每一个点都有一个唯一的编号 1~n 每一条边有一个边权,表示两个点之间的距离,ZGY 的宿舍在 S 点,机房在 T点,而小卖部在 H 点 现在 ZGY 想知道从宿舍经过小卖部到达机房的最短距离 不过因为在这个世界上有 Q个 ZGY,所以你必须回答 Q 个问题 很棒的数据分治题 读入里面说了会读入测试点编号-- 其实是很明显的暗示了-- 一半

机房测试5:silhouette(组合数+递推)

题目: 分析: (这道题是真的难)(声明: 在这位大佬的题解下多做了说明,图片来源也是他的博客.) 首先我们要发现一些小规律: 1.将A和B排序之后并不影响答案 证明:不管哪一列排序放到了哪里,那一列的最大值都应该是Ai. 2.A的最大一定等于B的最大: 很显然,如果不等于,那么最大值放在哪里都不合法. 3.将A和B数组按从小到大的顺序排序后,会变成这种矩形: 定义f[ i ]为至少有i行不满足,定义至少的原因:两两行之间不会受影响 显然最后我们要求的是恰好有0行不满足,即至少有0行不满足-至少