首页 > 其他分享 >P3327 [SDOI2015] 约数个数和

P3327 [SDOI2015] 约数个数和

时间:2024-09-12 22:24:03浏览次数:10  
标签:约数 P3327 limits sum mid mu SDOI2015 displaystyle

[SDOI2015] 约数个数和

题目描述

设 \(d(x)\) 为 \(x\) 的约数个数,给定 \(n,m\),求

\[\sum_{i=1}^n\sum_{j=1}^md(ij) \]

输入格式

输入文件包含多组测试数据。
第一行,一个整数 \(T\),表示测试数据的组数。
接下来的 \(T\) 行,每行两个整数 \(n,m\)。

输出格式

\(T\) 行,每行一个整数,表示你所求的答案。

样例 #1

样例输入 #1

2
7 4
5 6

样例输出 #1

110
121

提示

【数据范围】
对于 \(100\%\) 的数据,\(1\le T,n,m \le 50000\)。

链接

\(d(x)\)​的转化太艰难,考虑直接枚举约数进行统计。

\(d(ij)=\sum\limits_{x\mid i}\sum\limits_{y\mid j} [\gcd(x,y)=1]\)
....要是推不出上面这个式子这题的式子就打不开,不太能做。。。抽象。
当知识点记下来吧。 其实还挺好理解的。其实问题就是我怎么知道我要推它。。看起来很合理,但是这是知道了这个是结果后觉得合理。在不知道它是结果前,真的能够知道要用它吗?

\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^md(ij)\),用上面的式子转化,得到\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^m\sum\limits_{x\mid i}\sum\limits_{y\mid j} [\gcd(x,y)=1]\),再用\(\epsilon(n)=\displaystyle\sum_{d|n}\mu(d)\)
\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^m\sum\limits_{x\mid i}\sum\limits_{y\mid j} \displaystyle\sum_{d|x,d|y}\mu(d)\)

\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^m\sum\limits_{x\mid i}\sum\limits_{y\mid j} \displaystyle\sum_{d=1}^{d\leq min(x,y)}\mu(d)*[d|x]*[d|y]\)或者是\(\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^m\sum\limits_{x\mid i}\sum\limits_{y\mid j} \displaystyle\sum_{d=1}^{d\leq min(n,m)}\mu(d)*[d|x]*[d|y]\),发现后面的写法\(d\)与\(i,j\)无关,可以直接提前最后的d的枚举

\(\displaystyle\sum_{d=1}^{min(n,m)}\mu(d)\displaystyle\sum_{i=1}^{n}\displaystyle\sum_{j=1}^m\displaystyle\sum_{x|i}\displaystyle\sum_{y|j}[d|gcd(x,y)]\),然后后面的部分被动的枚举检测改为直接统计贡献。其实就是转为考虑满足\(\mu(d)\)能作为答案的是哪些部分

\(\displaystyle\sum_{d=1}^{min(n,m)}\mu(d)\displaystyle\sum_{i=1}^{\lfloor\frac n d\rfloor}\lfloor\frac n {di}\rfloor\displaystyle\sum_{j=1}^{\lfloor\frac m d\rfloor}\lfloor\frac m {dj}\rfloor\),整理一下就能得到前面的式子。
唯一的和莫反的板子的不同点就是\(d(ij)\)的转化。没了。不过后面的也不是完全常规,虽然思路是挺正常的。
后面的部分也不是普通的整除分块,循环本身是,内部又是,虽然两个重合起来不会脱离\(O(\sqrt n)\)的复杂度,但是写起来好麻烦。。。

从结论的式子上看,这题就和前面的题目明显不一样了。有很多对于莫反的变换的新的理解。约数枚举的提前其实并不是一个非常套路的东西,它有本身的规则,我之前都是感性理解的,导致问题其实挺大,因为不一定正确。本质就是如果里面的约数枚举的内容没有和前面的变量枚举相关的,那就直接用分配律提前就好。
所以其实完全可以把限制作为一个乘积写出来而不是追求所谓的"简洁"而写在循环内部。感觉是没有任何好处和方便的。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
	int a=0,b=1;char c=getchar();
	for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
	for(;c>='0'&&c<='9';c=getchar())a=a*10+c-'0';
	return a*b;
}
const int N=100000;
int prime[N+1],cnt,mu[N+1],vis[N+1],sum[N+1];ll f[N+1];
void init()
{
    mu[1]=1;
    for(int i=2;i<=N;i++)
    {
        if(!vis[i])prime[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&i*prime[j]<=N;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            {
                mu[i*prime[j]]=0;
                
                break;
            }
            mu[i*prime[j]]=mu[i]*mu[prime[j]];
        }
    }
    for(int i=1;i<=N;i++)
    {
        sum[i]=sum[i-1]+mu[i];
    }
    for(int i=1;i<=N;i++)
    {
        for(int l=1,r=0;l<=i;l=r+1)
        {
            r=i/(i/l);
            f[i]+=1LL*(i/l)*(r-l+1);
        }
    }
}
int main()
{
    init();
    int T=read();
    while(T--)
    {
        int n=read(),m=read();
        ll ans=0;
        for(int l=1,r=0;l<=min(n,m);l=r+1)
        {
            r=min(n/(n/l),m/(m/l));
            ans+=(sum[r]-sum[l-1])*(f[n/l])*(f[m/l]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

居然卡我常...

标签:约数,P3327,limits,sum,mid,mu,SDOI2015,displaystyle
From: https://www.cnblogs.com/HLZZPawa/p/18411245

相关文章

  • 题解:P5618 [SDOI2015] 道路修建
    题意给定一个\(2\timesN\)的网格,网格上的点和上下左右连边。要求支持以下几种操作:修改某条边的边权。求满足\(y\in[l,r]\)的点构成的点集的最小生成树。分析这道题的想法和P4246[SHOI2008]堵塞的交通很相似。注意到\(N,M\leq6\times10^4\),并且查询的是......
  • P3320 [SDOI2015] 寻宝游戏 与 P10930 异象石 与 CF176E Archaeology
    思路:考虑按照dfn序将关键点的集合排序后为\(a_0,a_1,\cdots,a_k\),则答案为:\[\frac{\sum\limits_{i=0}^k\operatorname{dis}(a_i,a_{(i+1)\bmodk})}{2}\]简单证明一下:需要找出包含一些关键点的最小联通导出子图。则随便以一个关键点为根,对于子树内没有关键点的子树直接......
  • 第五章习题3-输入两个正整数m和n,求其最大公约数和最小公倍数
     ......
  • 7-3 sdut-最大公约数和最小公倍数
    给定2个正整数,求它们的最大公约数和最小公倍数,并输出。输入格式:输入有若干组。每组数据,在一行中给出两个正整数M和N(≤1000),中间有1个空格。输出格式:对于每组输入,在一行中顺序输出M和N的最大公约数和最小公倍数,两数字间以1个空格分隔。输入样例:181220153926576......
  • P5176 公约数
    P5176公约数\[ans=\sum_{i=1}^{m}\sum_{j=1}^{m}\sum_{k=1}^{p}gcd(ij,jk,ik)\timesgcd(i,j,k)\times(\frac{gcd(i,j)}{gcd(i,k)\timesgcd(j,k))}+\frac{gcd(j,k)}{gcd(i,k)\timesgcd(i,j)}+\frac{gcd(i,k)}{gcd(i,j)\timesgcd(j,k)})\]$\quad$《这东......
  • Math、Tuple、公约数用法
    计算整数的商并返回余数点击查看代码intaa=5,bb=3;varcc=Math.DivRem(bb,aa,outintd);1.1.数值比较点击查看代码inta=3,b=3;varc1=Math.Max(a,b);varc=Math.Ceiling(a/(double)b);二元组用法点击查看代码List<Tuple<in......
  • C语言入门基础题:最大公约数(三个数间取最大公约数)
    1.题目描述输入三个正整数x,y,z,求它们的最大公约数(GreatestcommonDivisor)g:最大的正整数g>=1满足x,y,z都是g的倍数,即(x modg)=(ymodg)=(zmodg)=0。2.输入格式输入一行三个正整数x,y,z。3.输出格式输出一行一个整数g,表示x,y,z的最大公约数,4.输入......
  • 数论——绝对素数、素数筛法、埃氏筛法、欧拉筛法、最大公约数
    绝对素数绝对素数是指一个素数在其十进制表示下,无论是从左向右读还是从右向左读,所得到的数仍然是素数。例如,13是一个素数,从右向左读是31,31也是素数,所以13是一个绝对素数。#include<iostream>#include<cmath>usingnamespacestd;boolisPrime(intnum){if(......
  • 【每日一题】【DFS】【试除法求约数】【大剪枝】清楚姐姐跳格子 牛客周赛 Round 54 D
    牛客周赛Round54D题清楚姐姐跳格子题目背景牛客周赛Round54题目描述样例#1样例输入#1523154样例输出#12做题思路首先知道ai......
  • 基础数论 质数与约数
    基础数论前置芝士:等比数列求和:\(S_n=a_0\frac{1-q^n}{1-q}\)质数与约数:整除与约数设\(n\)为非负整数,\(d\)为正整数,若\(\frac{n}{d}\)为整数,则称\(d\)整除\(n\),记为\(d\midn\)。此时,则称\(d\)是\(n\)的约数,或因数、因子;称\(n\)为\(d\)的倍数。质数......