BZOJ2226:[SPOJ5971]LCMSum
Description
Input
Output
Sample Input
1
2
5
Sample Output
4
55
HINT
1 <= T <= 300000
1 <= n <= 1000000
题解:
题意即求∑LCM(i,n)(1<=i<=n)。
枚举gcd,统计对答案的贡献。
原本我采用的方法是容斥,求出n的因数表后,由大到小枚举gcd[i],并把更小的gcd[j]的贡献减去相应的值。
复杂度还可以,但是常数非常大,在BZ上过不了。
有一个常数更小的方法:枚举gcd后,我们需要知道1~n div gcd-1中所有与n div gcd互质的数的和。
设m=n div gcd。若x与m互质,则m-x与m互质,即与m互质的数成对出现,所以与m互质的数的和为m*φ(m)div 2。(m<=2时依旧成立)
线性筛预处理出欧拉函数,就可以快速求值了。
代码:
TLE的容斥(P++注意):
#include <bits/stdc++.h>
using namespace std;
#define begin {
#define end }
#define while while(
#define if if(
#define do )
#define then )
#define for for(
#define fillchar(a,b,c) memset(a,c,b)
#define writeln printf("\n")
#define write printf
#define readln readl()
#define inc(a) a++
#define dec(a) a--
#define exit(a) return a
#define mod %
#define div /
#define shl <<
#define shr >>
#define extended long double
#define longint int
#define integer short
#define int64 long long
template<typename T> inline void read(T& a)
begin
T x=,f=; char ch=getchar();
while(ch<'')or(ch>'')do
begin
if ch=='-' then f=-; ch=getchar();
end
while(ch>='')and(ch<='')do
begin
x=x*+ch-''; ch=getchar();
end
a=x*f;
end
inline void readl()
begin
char ch; ch=getchar();
while ch!='\n' do ch=getchar();
end
int64 i,t,ii,j,n,m,x,a[],b[],ans;
int main()
begin
read(t);
for ii=;ii<=t;ii++ do
begin
read(x); j=sqrt(x); n=; m=; ans=;
for i=;i<=j;i++ do
begin
if x mod i== then
begin
inc(n); a[n]=i;
if x div i>i then begin inc(m); a[-m]=x div i; end;
end
end
for i=n+;i<=n+m;i++ do a[i]=a[-(m-(i-n)+)];
n=n+m;
for i=;i<=n;i++ do b[a[i]]=;
for i=n;i>=;i-- do
begin
b[a[i]]=b[a[i]]+(+x div a[i])*(x div a[i])div ;
ans=ans+b[a[i]]*x;
j=;
while a[j]*a[j]<=a[i] do
begin
if j>n then break;
if a[i] mod a[j]== then
begin
b[a[j]]=b[a[j]]-(a[i] div a[j])*b[a[i]];
if(a[j]*a[j]<a[i])and(a[j]>)then
b[a[i] div a[j]]=b[a[i] div a[j]]-a[j]*b[a[i]];
end
inc(j);
end
end
write("%lld",ans); writeln;
end
end
标程(P++注意):
#include <bits/stdc++.h>
using namespace std;
#define begin {
#define end }
#define while while(
#define if if(
#define do )
#define then )
#define for for(
#define fillchar(a,b,c) memset(a,c,b)
#define writeln printf("\n")
#define write printf
#define readln readl()
#define inc(a) a++
#define dec(a) a--
#define exit(a) return a
#define mod %
#define div /
#define shl <<
#define shr >>
#define extended long double
#define longint int
#define integer short
#define int64 long long
template<typename T> inline void read(T& a)
begin
T x=,f=; char ch=getchar();
while(ch<'')or(ch>'')do
begin
if ch=='-' then f=-; ch=getchar();
end
while(ch>='')and(ch<='')do
begin
x=x*+ch-''; ch=getchar();
end
a=x*f;
end
inline void readl()
begin
char ch; ch=getchar();
while ch!='\n' do ch=getchar();
end
longint p[],vis[],ph[],pcnt=,T,n;
void init_p()
begin
ph[]=; ph[]=;
int64 temp;
for int i=;i<;i++ do
begin
if not vis[i] then
begin
p[pcnt]=i; ph[i]=i-; inc(pcnt);
end
for int j=;j<pcnt&&(temp=(int64)p[j]*i)<;j++ do
begin
vis[temp]=;
if i mod p[j]== then begin ph[temp]=ph[i]*p[j]; break; end
else ph[temp]=ph[i]*(p[j]-);
end
end
end
int64 solve(int n)
begin
int64 ans=0ll;
longint half=(int)(sqrt(n)+0.01);
if half*half==n then begin ans+=1ll*ph[half]*half/; dec(half); end
inc(ans); ans+=1ll*ph[n]*n/;
for int i=;i<=half;i++ do
if n mod i== then
begin
ans+=1ll*ph[i]*i/;
ans+=1ll*ph[n/i]*n/i/;
end
exit(ans*n);
}
int main()
begin
read(T); init_p();
for int i=;i<=T;i++ do
begin read(n); write("%lld",solve(n)); writeln; end
return ;
end
BZOJ2226:[SPOJ5971]LCMSum的更多相关文章
- [BZOJ2226][SPOJ5971]LCMSum(莫比乌斯反演)
2226: [Spoj 5971] LCMSum Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 1949 Solved: 852[Submit][S ...
- [bzoj2226][Spoj5971]LCMSum_欧拉函数_线性筛
LCMSum bzoj-2226 Spoj-5971 题目大意:求$\sum\limits_{i=1}^nlcm(i,n)$ 注释:$1\le n\le 10^6$,$1\le cases \le 3 ...
- BZOJ2226 & SPOJ5971:LCMSum——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2226 题目大意:给定一个n,求lcm(1,n)+lcm(2,n)+……+lcm(n,n). ———— ...
- AHOI2018训练日程(3.10~4.12)
(总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...
- 【BZOJ2226】[Spoj 5971] LCMSum 莫比乌斯反演(欧拉函数?)
[BZOJ2226][Spoj 5971] LCMSum Description Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n ...
- BZOJ2226: [Spoj 5971] LCMSum
题解: 考虑枚举gcd,然后问题转化为求<=n且与n互质的数的和. 这是有公式的f[i]=phi[i]*i/2 然后卡一卡时就可以过了. 代码: #include<cstdio> # ...
- BZOJ2226:LCMSum(欧拉函数)
Description Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes t ...
- [BZOJ2226]LCMSum
转化一下,$\sum\limits_{i=1}^n[i,n]=n\sum\limits_{i=1}^n\dfrac i{(i,n)}$ 枚举$d=(i,n)$,上式变为$n\sum\limits_{d ...
- 【bzoj2226】[Spoj 5971] LCMSum 欧拉函数
题目描述 Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Leas ...
随机推荐
- Async_Study
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- MyBatis mappers元素标签及其属性、配置
mappers:映射器,以最佳的方式是告诉 MyBatis 到哪里去找映射文件. <!-- 使用相对于类路径的资源引用,要满足一个条件:1.即映射文件只要放在类路径下,就可以根据相对路径找到,放 ...
- 常用的css解决方案
一. css 2.x code 1. 文字换行 /*强制不换行*/ white-space:nowrap; /*自动换行*/ word-wrap: break-word; word-break: n ...
- HduOJ 2162 - Primes
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2161 题意:判断n是不是素数,输入到0停止.题目规定1 2 都不是素数. 题解:筛素数.老题目.不过这 ...
- Winform 获取桌面设备上下文
//获得桌面设备上下文 us(Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { g.DrawLine(Pens.Red, , , , ); }
- Producer-Consumer 生产者,消费者
这个模式跟Guarded模式有点类似,不过需要一个控制台限制请求方和处理方的频度和数量. public class ProducerConsumerTest { /** * @param args * ...
- CF528E Triangles3000
题意:给你一个不存在三线共交点的一次函数组a[i]x+b[i]y+c[i]=0. 问等概率选取三条直线,围成三角形的面积的期望. n<=3000. 标程: #include<bits/st ...
- Java中的常量池
JVM中有: Class文件常量池.运行时常量池.全局字符串常量池.基本类型包装类对象 常量池 Class文件常量池: class文件是一组以字节为单位的二进制数据流,在java代码的编译期间,编写的 ...
- 解析JQuery Ajax
jQuery是一个挺好的轻量级的JS框架,能帮助我们快速的开发JS应用,并在一定程度上改变了我们写JavaScript代码的习惯. 先来看一些简单的方法,这些方法都是对jQuery.ajax()进行封 ...
- git 使用案例(本地仓库无缝迁移远程仓库)
之前都是直接从gitlab上clone代码,然后把本地代码copy过去,然后push.有点麻烦,查询了一下如何无缝从本地仓库迁移到远程仓库.记录一波... 下面的例子采用github来做例子. 1. ...