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 ...
随机推荐
- jQuery 表单域选中选择器
复选框.单选按钮.下拉列表 /***********************************************/ <script type="text/javascrip ...
- 6 Accessing and Managing Symbols with armlink
6.4 Image$$ execution region symbols The linker generates Image$$ symbols for every execution region ...
- spark1.0.2读取hbase(CDH0.96.1)上的数据
基本环境: 我是在win7环境下,spark1.0.2,HBase0.9.6.1 使用工具:IDEA14.1, scala 2.11.6, sbt.我现在是测试环境使用的是单节点 1.使用IDEA创建 ...
- Codeforces Round #526 D - The Fair Nut and the Best Path /// 树上两点间路径花费
题目大意: 给定一棵树 树上每个点有对应的点权 树上每条边有对应的边权 经过一个点可得到点权 经过一条边必须花费边权 即从u到v 最终得分=u的点权-u到v的边权+v的点权 求树上一条路径使得得分最大 ...
- USACO2005 City Skyline /// oj23401
题目大意: Input * Line 1: Two space separated integers: N and W * Lines 2..N+1: Two space separated inte ...
- python接口自动化(接口基础)
一.什么是接口? 前端负责展示和收集数据 后端负责处理数据,返回对应的结果 接口是前端与后端之间的桥梁,传递数据的通道 二.
- 2018-10-8-Win10-使用-GHO-安装出现-UWP-软件打开闪退-应用商店无法安装软件
title author date CreateTime categories Win10 使用 GHO 安装出现 UWP 软件打开闪退 应用商店无法安装软件 lindexi 2018-10-8 18 ...
- 浏览器自带记忆功能,使input颜色和字体丢失
方法一 : 会有视觉上颜色的变化input:-internal-autofill-selected { /*内置阴影填充 背景颜色*/ box-shadow: inset 0 0 0 1000px # ...
- MySQL 笔记一
一.基本语法 1.数据库操作 create database [IF NOT EXIEST ] 数据库名 --创建数据库 drop database 数据库名 ...
- [JZOJ 5788] 餐馆
思路: 考虑树形dp. 我们设\(dp[i][j][0/1]\)表示在\(i\)为根的子树中花费\(j\)单位时间,最终回到/不必回到\(i\)的最大收益. 转移三种: \(dp[x][j][0] = ...