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 ...
随机推荐
- iOS cocos2d安装以及问题解决
一:下载: 首先要去Cocos2d和Cocos2d-x网站下载相关的工具: 1.Cocos2d下载地址:http://www.cocos2d-iphone.org,然后进入Download页面,下边有 ...
- JDK 1.8 源码阅读和理解
根据 一篇文章教会你,如何做到招聘要求中的“要有扎实的Java基础” 的指引,决定开始阅读下JDK源码. 本文将作为源码阅读总纲 一.精读部分 java.io java.lang java.util ...
- go defer (go延迟函数)
go defer (go延迟函数) Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此.根据GO LANGUAGE SPEC的说法: A "defer" sta ...
- Java 银行家算法
实验存档,代码特别烂.. 测试.java package operating.test; import operating.entity.bank.Bank; import operating.ent ...
- Cat 跨线程之 TaggedTransaction 用法和原理分析
代码 package com.dianping.cat.message.internal; import com.dianping.cat.Cat; import com.dianping.cat.m ...
- 安装MongoDB步骤
1.第一步是从官网下载匹配自己操作系统的安装文件或压缩文件: 2.随便找个文件夹先解压安装文件,然后在C盘根目录建立一个新文件夹命名为mongodb: 3.将打开刚刚安装的文件,将bin文件夹拷贝到C ...
- spring_boot_pay支付宝,微信,银联支付详细代码案例
spring-boot-pay 支付服务:支付宝,微信,银联详细代码案例(除银联支付可以测试以外,支付宝和微信支付测试均需要企业认证,个人无法完成测试),项目启动前请仔细阅读 注意事项 . 友情提示 ...
- 聊聊API网关的作用
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 10.5px "Trebuchet MS" } p.p2 { margin: 0.0px ...
- jquery提供的插件无法删除cookie的解决办法
之前使用jquery的cookie插件提供的 $.cookie("key",null)方法删除cookie,结果发现代码中的cookie一直无法删除,导致后面的种种问题. 经过各种 ...
- JavaScript Array 对象方法 以及 如何区分javascript中的toString()、toLocaleString()、valueOf()方法
1.concat() 2.join() 3.pop() 4.push() 5.reverse() 6.shift() 7.unshift() 8.slice() 9.sort() 10.splice( ...