51nod 1575 Gcd and Lcm
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1575
万年巨坑终于填掉了……
首先是煞笔西瓜的做题历程O_O。
原题要求$\sum_{i=1}^n\sum_{j=1}^i\sum_{k=1}^i [(i,j),(i,k)]$
那么先推一波式子吧
balabala
我也忘记自己是怎么推的了(雾
总之最后推出来是这样的
$ ans=\sum_{i=1}^{n} f(\left\lfloor\frac{n}{i}\right\rfloor)*g(i) $
其中 $ f(x)=\sum_{i=1}^{x} μ(i)*i^2*\frac{\frac{x}{i}(\frac{x}{i}+1)}{2} $ ,$ g(x)=[\sum_{d|x} \frac{x}{d}*φ(d)]^2 $
然后接下来的问题就是怎么求f(x)的值和g(x)的前缀和了,求出来就能分段计算辣。
嗯……
想想怎么求……
$ μ(i)*i^2 $ 可以用杜教筛直接求嘛,然后f(x)就可以O(3/4)分段求,可是在总式里面再跑一次分段的话复杂度会……诶,不管了,先写。
g(x)的前缀和可以洲阁筛求,嗯,码码码……(这么复杂的题怎么才7级?
啊,T了,意料之中……
改改改
跑得越来越快了……
诶,极限数据要跑两秒多,可是10组数据的话还是要10多秒
改不动,弃坑……
(51nod群上问了下,夹克老爷说他不会。
问问YJQ
他说$ \sum_{j=1}^i\sum_{k=1}^i [(i,j),(i,k)] $ 这东西是个积性函数。
所以直接用洲阁筛对这个东西求前缀和就好了(掀桌……
也就是说,看到题目,你开始推式子,你就输辣。
具体来说,对于一个质数$ p $,当 $ i=p^k $ 时,$ \sum_{j=1}^i\sum_{k=1}^i [(i,j),(i,k)] =(2k+1)*(p^{2k}-p^{2k-1})+p^{k-1} $
优越写法才2.8k,第一种方法直接上5k……
代码不贴辣。
upd at 2017.4.26好像这题烂大街了,我来发个洲阁筛模板吧
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ui unsigned int
#define ull unsigned long long
#define MN 100001
#define SQ 64000
using namespace std;
ui read_p,read_ca;
inline ui read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
const ui HA=1e6+;
ui T,n,MMH,p[MN/],_p[MN/],num=,TTT,O,Num,f[SQ],_S[SQ],G_2[SQ],G_1[SQ],G_0[SQ],_T[SQ],P_P[MN/],_G_2[MN/],_G_1[MN/],_O[SQ],_Num,_l[HA],NNN=,LL;bool bo[MN];
ui gcd(ui x,ui y){return y?gcd(y,x%y):x;}
ui _b_y[HA],_b_z[HA],_b_ne[HA];
inline void _in(ui x,ui y,ui z){_b_y[++_Num]=y;_b_z[_Num]=z;_b_ne[_Num]=_l[x];_l[x]=_Num;}
inline ui Q_2(ui x){if (x%==)return (ull)(x+x+)*(x+)/*x;else if (x%==) return (ull)(x+x+)*x/*(x+);else return (ull)x*(x+)/*(x+x+);}
inline ui Q_1(ui x){return (ull)x*(x+)>>;}
inline ui sqr(ui x){return x*x;}
inline ui min(ui a,ui b){return a<b?a:b;}
inline ui find(ui x){
if (x<HA) return _b_z[_l[x]];
register ui i;
for (i=_l[x%HA];i;i=_b_ne[i]) if (_b_y[i]==x) return _b_z[i];
return ;
}
inline ui Mmh(ui n){
register ui i,j,c;ui o=sqrt(n)+1e-,MMH=,k=,R,Ls,Rs,P,SS=;ull x,Q,O_O;
while (p[LL+]<=o&&LL<num) LL++;
for (i=;i<=n;i=j+) j=n/(c=n/i),_S[++k]=c,_in(c%HA,c,k),_T[k]=f[k]=,G_2[k]=Q_2(c),G_1[k]=Q_1(c),G_0[k]=c;
for (i=k,j=;i;_O[i--]=j) while (_S[i]>=p[j+]) j++;
for (f[i=]=,P=Ls=Rs=k;i<=LL;i++){
if (i==) while (_S[P]<_p[i]&&P) P--;else P=Rs;
while (_S[Rs]<_p[i+]&&Rs) SS+=f[Rs--];
while (_S[Ls]<p[i+]&&Ls) SS-=f[Ls--];
if (i!=LL) MMH+=SS*P_P[i+];
for (j=P;j;j--)
if (f[j]){
for (x=p[i],Q=,c=;x<=_S[j];x*=p[i],Q*=p[i],c++){
R=find(_S[j]/x);
f[R]+=(O_O=f[j]*((*c+)*(p[i]-)*sqr(Q)*p[i]+Q));if (Ls>=R&&R>Rs) SS+=O_O;
if (i!=LL) if (_S[R]>=p[i+]&&_S[R]<_p[i+]) MMH+=O_O*P_P[i+];
}
}
for (j=;j<=P;j++)
if (_S[j]>=p[i]) c=min(i-,_O[R=find(_S[j]/p[i])]),
G_2[j]-=_p[i]*(G_2[R]-(_G_2[c]-_G_2[_T[R]]))+(_G_2[i-]-_G_2[_T[j]]),
G_1[j]-=p[i]*(G_1[R]-(_G_1[c]-_G_1[_T[R]]))+(_G_1[i-]-_G_1[_T[j]]),
G_0[j]-=(G_0[R]-(c-_T[R]))+(i--_T[j]),_T[j]=i;
}
for (j=;j<=k;j++) c=min(LL,_O[j]),G_2[j]-=_G_2[c]-_G_2[_T[j]],G_1[j]-=_G_1[c]-_G_1[_T[j]],G_0[j]-=c-_T[j];
for (i=;i<=k;i++) MMH+=f[i]*((G_2[i]-G_1[i])*+G_0[i]),_l[_S[k]%HA]=;
return _Num=,MMH;
}
int main(){
register ui i,j;
for (i=;i<MN;i++){
if (!bo[i]) p[++num]=i,_p[num]=p[num]*p[num],_G_2[num]=_G_2[num-]+_p[num],_G_1[num]=_G_1[num-]+p[num],P_P[num]=*p[num]*(p[num]-)+;
for (j=;j<=num&&(O=i*p[j])<MN;j++){
bo[O]=;
if (!i%p[j]) break;
}
}
T=read();while(T--){
n=read();
printf("%u\n",Mmh(n));
}
}
51nod 1575 Gcd and Lcm的更多相关文章
- 51Nod 2026 Gcd and Lcm
题目传送门 分析: 开始玩一个小小的trick 我们发现\(f(n)=\sum_{d|n}\mu(d)\cdot d\)是一个积性函数 所以: \(~~~~f(n)=\prod f(p_i^{a_i} ...
- HDOJ 4497 GCD and LCM
组合数学 GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- hdu 4497 GCD and LCM 数学
GCD and LCM Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4 ...
- GCD 与 LCM UVA - 11388
题目链接: https://cn.vjudge.net/problem/23709/origin 本题其实有坑 数据大小太大, 2的32次方,故而一定是取巧的算法,暴力不可能过的 思路是最大公因数的倍 ...
- 简单数论总结1——gcd与lcm
并不重要的前言 最近学习了一些数论知识,但是自己都不懂自己到底学了些什么qwq,在这里把知识一并总结起来. 也不是很难的gcd和lcm 显而易见的结论: 为什么呢? 根据唯一分解定理: a和b都可被分 ...
- poj 2429 GCD & LCM Inverse 【java】+【数学】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9928 Accepted: ...
- HDU 4497 GCD and LCM (合数分解)
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
- hdu4497 GCD and LCM
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total S ...
- HDU 4497 GCD and LCM(数论+容斥原理)
GCD and LCM Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total ...
随机推荐
- 【java】获取当前日期时间:java.util.Date
public class TestDate { public static void main(String[] args) { System.out.println(new java.util.Da ...
- Spring(概念)
在本文中只讲述一些概念性的东西,因为我在开始学习JAVA的时候对这些概念性的东西总是不太理解,总结总结再感悟一下,也方便后人. 理解的不深,用通俗的语言讲一下: 百度百科这样介绍: spring框架主 ...
- c语言项目流程开发三部曲
一.这一部曲是紧接第二部没有介绍完的内容,主要是函数接口实体的实现,代码比较多,如果没有看前两部曲的先去看看,再来看这里,不然不好理解,话不说多上代码, #define _CRT_SECURE_NO_ ...
- ArcGIS API for JavaScript 4.2学习笔记[25] 官方第八章Analysis(空间查询)概览与解释
开森,最关注的空间分析章节终于到了,在空间查询那节逻辑性的代码简直要命(呵呵,空间分析的代码也要命...). 上目录截图: [Geodesic buffers(GeometryEngine)] 使用G ...
- bzoj 4569: [Scoi2016]萌萌哒
Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两个长度相同的 ...
- js 自定义html标签属性
<input type="text" id="txtBox" displayName="123456" /> 获取自定义属性值: ...
- Oracle学习笔记_09_字符串相关函数
二.参考资料 0.Oracle中的字符串类型及相关函数详解 1.ORACLE 字符串操作 2.oracle函数大全-字符串处理函数
- C# 给枚举类型增加一个描述特性
前言 相信很多人对枚举并不陌生,枚举可以很方便和直观的管理一组特定值.如果我们在页面上直接输出我们希望匹配的汉语意思或则其他满足我们需求的语句就更好了,当然,通常小伙伴们都会再页面上if(enum== ...
- mysql 数据表字段修改sql 语句
1 新增字段 alter table bulletin add citycode varchar(6) not null default 0 [after `id`]; # 城市代码 2 修改字段 a ...
- Java的按位操作符
本文参考:Java的位操作符 Java的位操作符用来操作整数基本数据类型中的单个"比特"(bit),即代进制位.而我们知道比特就是0和1,那么,位操作就是对这些数据进行基本的操作. ...