首页 > 其他分享 >[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)

[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)

时间:2023-02-21 10:05:59浏览次数:56  
标签:约数 square Min LL 容斥 ret mu MAXN sum


题目

vjudge URL:​​Counting Divisors (square) ​​​ Let [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数 be the number of positive divisors of [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_02.

For example, [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_03, [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_04 and [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_05.

Let [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_06

Given [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_07, find [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_08.

Input

First line contains [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_09 ([SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_10), the number of test cases.

Each of the next [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_09 lines contains a single integer [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_07. ([SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_13)

Output

For each number [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_07, output a single line containing [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_08.

Example
  • Input

5
1
2
3
10
100

  • Output

1
4
7
48
1194

  • Explanation for Input
    [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_16
Information

There are 6 Input files.

  • Input #1: [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_17, TL = 1s.
  • Input #2: [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_18, TL = 20s.
  • Input #3: [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_19, TL = 20s.
  • Input #4: [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_20, TL = 20s.
  • Input #5: [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_21, TL = 20s.
  • Input #6: [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_22, TL = 20s.

My C++ solution runs in 5.3 sec. (total time) //呵呵

Source Limit is 6 KB.*

题目分析

[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数表示[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_02的约数个数,即

前言
  • mdzz,写了1h的Latex公式没保存。。因为机房电脑的烂CPU,本地测这道题的极限数据时崩溃了c
  • 这道题是真的卡常,最后点线性筛必须筛到很大,5e7能过,1e7、2e7都不行(可能因为我是大常数选手吧,悄悄打上卡常的FLAG)
  • 本地评测炸电脑,真的无语。。
  • 刚开始模了1e9+7 WA了好久。。。
  • 由于是求函数前缀和,又和杜教筛的题一起做的,就放在杜教筛/莫比乌斯反演里吧
正文

[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_25
[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_26
[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_27看作是 只由[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_28(乘起来)构成的[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_02的约数的个数,因为每一个约数都对答案造成了对应的[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_30的贡献,那么
[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_31其中[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_32表示d的质因子的个数(想想)
与此同时,我们又发现[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_33实质上是[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_34的质因子选或不选的方案数,也就是[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_02无平方因子的约数的个数,则
[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_36因为根据[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_37函数的定义,只有无平方因子数的函数值才为[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_38[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_39,加上绝对值就相当于统计了个数(有的题解也写的是[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_40,个人认为第一眼看到这个平方会懵一会)
[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_41

  • 先看第二个[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_42,对于某一个[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_43的取值,把它记作[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_44,就以[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_44的范围做整除分块优化,[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_46的时间复杂度,那么外层还有一个求和,于是在外面也套一层整除分块优化,预处理出前[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_47后时间复杂度为[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_48
  • 此处预处理为线性筛,考虑变换,[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_49实际可看作枚举[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_50后看[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_51以内有多少个数能被[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_50整除,这不就是[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_53吗?
    于是我们只需要筛出约数个数在累加就行了,线性筛时存一下当前数的最小质因子的次数就可以愉快的线性筛了
  • 由于在外面一层套上了整除分块优化,则需要求出[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_54的前缀和,也就是[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_线性筛_55以内的无平方因子数
  • 这里处理无平方因子数时用容斥原理,有
    [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_56想想[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_57函数的定义,这个容斥还是比较好理解的
    [SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_58可处理出来

综上,各种操作之后把时间复杂度降到了[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_59

等等,真的降到了吗??!看看降到[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_约数个数_59的条件?

  • 预处理出前[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_5e_47

然而掀桌)
所以只能尽可能的接近,实测[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_62能过,[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_63都会TLE

CAUTION

首先做这道题,如果电脑是机房的老电脑/旧电脑/烂电脑,不要像作死去测什么[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_64的极限数据,反正我是卡爆了(逃)
也不要像我一样边写代码边写博客,更不要卡住之后作死的乱点一气把浏览器搞炸了,我写了[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_卡常_65[SPOJ] DIVCNT2 - Counting Divisors (square) (平方的约数个数前缀和 容斥 卡常)_容斥_66啊!!!(这里的公式已经是精简版了)
最后一句忠告,写博客多按保存(富文本编辑器似乎会过一会就自动保存一下,不过不能写数学公式),写代码也是…

AC code
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MAXN = 5e7 + 1;//!!!
int Prime[MAXN], mu[MAXN], d[MAXN], Min_a[MAXN], Cnt;
bool IsnotPrime[MAXN];
LL sum_d[MAXN], sum_mu[MAXN];
void init(int n)//线性筛,Min_a[i]存的是i最小质因子的次数
{
d[1] = mu[1] = 1;
for(int i = 2; i <= n; ++i)
{

if(!IsnotPrime[i])
Prime[++Cnt] = i, mu[i] = -1, d[i] = 2, Min_a[i] = 1;
for(int j = 1, v; j <= Cnt && i * Prime[j] <= n; ++j)
{
v = i * Prime[j];
IsnotPrime[v] = 1; Min_a[v] = 1;
if(i % Prime[j] == 0)
{
Min_a[v] += Min_a[i];
mu[v] = 0;
d[v] = d[i] / Min_a[v] * (Min_a[v] + 1);
break;
}
mu[v] = -mu[i];
d[v] = d[i]<<1;
}
}
for(int i = 1; i <= n; ++i)
sum_d[i] = sum_d[i-1] + d[i],
sum_mu[i] = sum_mu[i-1] + mu[i]*mu[i];
}
inline LL Sum_mu(LL n)//莫比乌斯函数的绝对值的前缀和/[1,n]无平方因子数个数
{
if(n < MAXN) return sum_mu[n];
LL ret = 0;
for(LL i = 1; i*i <= n; ++i)
ret += mu[i] * (n/(i*i));
return ret;
}
inline LL Sum_d(LL n) //约数个数前缀和
{
if(n < MAXN) return sum_d[n];
LL ret = 0;
for(LL i = 1, j; i <= n; i=j+1)
{
j = n/(n/i);
ret += (n/i) * (j-i+1);
}
return ret;
}

inline LL solve(LL n)
{
LL ret = 0;
for(LL i = 1, j; i <= n; i=j+1)
{
j = n/(n/i);
ret += (Sum_mu(j)-Sum_mu(i-1)) * Sum_d(n/i);
}
return ret;
}

int main ()
{
LL T, n;
scanf("%lld", &T);
init(T > 800 ? 10000 : MAXN-1); //优化
while(T--)
{
scanf("%lld", &n);
printf("%lld\n", solve(n));
}
}

参见 ​​传送门:大佬博客​​ …



再次吐槽数学公式的难打


标签:约数,square,Min,LL,容斥,ret,mu,MAXN,sum
From: https://blog.51cto.com/u_15973510/6075821

相关文章

  • [51Nod 1237] 最大公约数之和 (杜教筛+莫比乌斯反演)
    题目描述求题目分析乍一看十分像裸莫比乌斯反演,然而的范围让人望而却步于是先变化一下式子枚举令k=Td则此时可以整除分块优化,每次算出相等的上下界后用莫比乌斯反演计......
  • [bzoj 1471] 不相交路径 (容斥原理)
    题目描述给出一个结点的有向无环简单图。给出个不同的点,,,,定义不相交路径为两条路径,两条路径的起点分别为和,对应的两条路径的终点为和,要求满足这两条路径不相交,即两条路径上没......
  • [Sdoi2013] [bzoj 3198] spring (hash+容斥原理)
    题目描述给出个维坐标,求有多少对点对满足恰好个位置相等坐标数值在以内题目分析这道题一看就是hash容斥原理,用个位置对应相等个位置对应相等个位置对应相等的…但是不能......
  • [bzoj 2393] Cirno的完美算数教室 (容斥原理+dfs剪枝)
    题目描述发现了一种数,这种数呢只含有和两种数字现在想知道中有多少个数能被数整除  1<L<R<10^{10}题目分析由于R<10^{10},最大只有10位的数可以对答案造成贡献,每一位只能......
  • Count the Number of Square-Free Subsets
    CounttheNumberofSquare-FreeSubsetsYouaregivenapositiveinteger0-indexed array nums .Asubsetofthearray nums issquare-free iftheproduct......
  • ACwing 区间最大公约数题解 线段树(附证明)
    算进区间最大公因数单点线段树 https://www.acwing.com/problem/content/247/题目:给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:Clrd,表......
  • 约数之和
    约数之和假设现在有两个自然数$A$和$B$,$S$是$A^B$的所有约数之和。请你求出$S\bmod9901$的值是多少。输入格式在一行中输入用空格隔开的两个整数$A$和$B$......
  • C语言:求最大公约数和最小公倍数
    #include<stdio.h>//任意输入两个整数,输出这两个数的最大公约数和最小公倍数main(){inta,b,c,gys,gbs;scanf("%d%d",&a,&b);for(c=a;c>=1;c--)......
  • [LeetCode] 1139. Largest 1-Bordered Square
    Givena2D grid of 0sand 1s,returnthenumberofelementsin thelargest square subgridthathasall 1sonits border,or 0 ifsuchasubgrid doe......
  • 求最大公约数伪代码
    1.上网查找什么是求两个数的最大公约数的欧几里得算法(辗转相除法),提交算法说明和网上链接。2.参考教材,用伪代码(英语或汉语)实现欧几里得算法(辗转相除法),提交伪代码。3.选择......