JZOJ 5701. 【gdoi2018 day2】第一题 谈笑风生(magic)
Description
Input
Output
Sample Input
5 7 66
4 3 2 1 5
1 2
1 5
2 3
2 4
2 5
3 4
3 5
Sample Output
6 64
Data Constraint
Hint
Solution
这题的瓶颈就在于如何快速地求出边权的大小。
求出来后就可以直接二分答案+spfa了。
考虑莫比乌斯反演(设边两端的权值分别为 n,m (n<m)n,m(n<m)n,m\ (n):
设函数
f(d)=∑i=1n∑j=1m(i+j)[gcd(i,j)=1]f(d)=∑i=1n∑j=1m(i+j)[gcd(i,j)=1]f(d)=\sum_{i=1}^n\sum_{j=1}^m(i+j)[gcd(i,j)=1]
显然我们要求的答案即为 f[1]f[1]f[1] ,但是直接求 fff 并不容易,于是我们再设函数
g(d)=∑i=1n∑j=1m(i+j)[d|gcd(i,j)]" role="presentation">g(d)=∑i=1n∑j=1m(i+j)[d|gcd(i,j)]g(d)=∑i=1n∑j=1m(i+j)[d|gcd(i,j)]g(d)=\sum_{i=1}^n\sum_{j=1}^m(i+j)[d|gcd(i,j)]
那么则有:
g(d)=∑i=1⌊nd⌋f(di)g(d)=∑i=1⌊nd⌋f(di)g(d)=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(di)
反演得:
f(d)=∑i=1⌊nd⌋g(di)∗μ(i)f(d)=∑i=1⌊nd⌋g(di)∗μ(i)f(d)=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}g(di)*μ(i)
于是 ggg 可以直接求,用两次等差数列求和来表示:(首项+末项)*项数/2。
第一次等差数列变换:
g(d)=∑i=1⌊nd⌋di∗⌊md⌋+(d+⌊md⌋∗d)∗⌊md⌋2" role="presentation">g(d)=∑i=1⌊nd⌋di∗⌊md⌋+(d+⌊md⌋∗d)∗⌊md⌋2g(d)=∑i=1⌊nd⌋di∗⌊md⌋+(d+⌊md⌋∗d)∗⌊md⌋2g(d)=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}di*\lfloor\frac{m}{d}\rfloor+\frac{(d+\lfloor\frac{m}{d}\rfloor*d)*\lfloor\frac{m}{d}\rfloor}{2}
(原理就是 iii 的贡献和 j" role="presentation" style="position: relative;">jjj 的贡献分开算,jjj 的贡献满足等差数列的形式)
第二次等差数列变换:
g(d)=(d+⌊md⌋∗d)∗⌊nd⌋∗⌊md⌋2+(d∗⌊md⌋+d∗⌊nd⌋∗⌊md⌋)∗⌊nd⌋2" role="presentation">g(d)=(d+⌊md⌋∗d)∗⌊nd⌋∗⌊md⌋2+(d∗⌊md⌋+d∗⌊nd⌋∗⌊md⌋)∗⌊nd⌋2g(d)=(d+⌊md⌋∗d)∗⌊nd⌋∗⌊md⌋2+(d∗⌊md⌋+d∗⌊nd⌋∗⌊md⌋)∗⌊nd⌋2g(d)=\frac{(d+\lfloor\frac{m}{d}\rfloor*d)*\lfloor\frac{n}{d}\rfloor*\lfloor\frac{m}{d}\rfloor}{2}+\frac{(d*\lfloor\frac{m}{d}\rfloor+d*\lfloor\frac{n}{d}\rfloor*\lfloor\frac{m}{d}\rfloor)*\lfloor\frac{n}{d}\rfloor}{2}
g(d)=d∗(2+⌊nd⌋+⌊md⌋)∗⌊nd⌋∗⌊md⌋2g(d)=d∗(2+⌊nd⌋+⌊md⌋)∗⌊nd⌋∗⌊md⌋2g(d)=\frac{d*(2+\lfloor\frac{n}{d}\rfloor+\lfloor\frac{m}{d}\rfloor)*\lfloor\frac{n}{d}\rfloor*\lfloor\frac{m}{d}\rfloor}{2}
原理也是一样,带 iii 的项满足等差数列的形式,而后面的常数项先提出来。
于是我们可以表示出 f(d)" role="presentation" style="position: relative;">f(d)f(d)f(d) ,即:
f(d)=∑i=1⌊nd⌋g(di)∗μ(i)f(d)=∑i=1⌊nd⌋g(di)∗μ(i)f(d)=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}g(di)*μ(i)
f(d)=∑i=1⌊nd⌋di∗(2+⌊ndi⌋+⌊mdi⌋)∗⌊ndi⌋∗⌊mdi⌋2∗μ(i)f(d)=∑i=1⌊nd⌋di∗(2+⌊ndi⌋+⌊mdi⌋)∗⌊ndi⌋∗⌊mdi⌋2∗μ(i)f(d)=\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\frac{di*(2+\lfloor\frac{n}{di}\rfloor+\lfloor\frac{m}{di}\rfloor)*\lfloor\frac{n}{di}\rfloor*\lfloor\frac{m}{di}\rfloor}{2}*μ(i)
那我们要求的 f(1) (d=1)f(1)(d=1)f(1)\ (d=1) 就能长成这样:
f(1)==∑i=1ni∗(2+⌊ni⌋+⌊mi⌋)∗⌊ni⌋∗⌊mi⌋2∗μ(i)f(1)==∑i=1ni∗(2+⌊ni⌋+⌊mi⌋)∗⌊ni⌋∗⌊mi⌋2∗μ(i)f(1)==\sum_{i=1}^{n}\frac{i*(2+\lfloor\frac{n}{i}\rfloor+\lfloor\frac{m}{i}\rfloor)*\lfloor\frac{n}{i}\rfloor*\lfloor\frac{m}{i}\rfloor}{2}*μ(i)
对于 ⌊ni⌋⌊ni⌋\lfloor\frac{n}{i}\rfloor ,⌊mi⌋⌊mi⌋\lfloor\frac{m}{i}\rfloor 这样的形式我们都可以分块解决(值最多只有 O(n−−√+m−−√)O(n+m)O(\sqrt n+\sqrt m) 种)。
同时维护一个前缀和 pre[i]pre[i]pre[i] 即可:
pre[i]=∑j=1ij∗μ(j)pre[i]=∑j=1ij∗μ(j)pre[i]=\sum_{j=1}^{i}j*μ(j)
这样分块计算时就可以把值相同的一段段算了。
于是我们就快速地求出了边权,剩下的二分+spfa就很简单了。
总时间复杂度 O(m∗(Ax−−−√+Ay−−−√)+km∗log T)O(m∗(Ax+Ay)+km∗logT)O(m*(\sqrt{A_x}+\sqrt{A_y})+km*log\ T) 。
Code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long LL;
const int N=1e4+5;
int n,m,tot;
LL T,ans;
int first[N],nex[N<<2],en[N<<2];
LL w[N<<2];
int a[N],q[N*10],f[N],miu[N],pre[N];
bool bz[N];
LL dis[N];
inline int read()
{int X=0,w=0; char ch=0;while(!isdigit(ch)) w|=ch=='-',ch=getchar();while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();return w?-X:X;
}
inline int min(int x,int y)
{return x<y?x:y;
}
inline void insert(int x,int y,LL z)
{nex[++tot]=first[x];first[x]=tot;en[tot]=y;w[tot]=z;
}
inline bool check(LL val)
{memset(dis,60,sizeof(dis));memset(bz,false,sizeof(bz));int l=dis[1]=0,r=q[1]=1;while(l<r){if(dis[n]<=T) return true;int x=q[++l];bz[x]=false;for(int i=first[x];i;i=nex[i]){LL vv=w[i]-val<0?0:w[i]-val;if(dis[x]+vv<dis[en[i]]){dis[en[i]]=dis[x]+vv;if(!bz[en[i]]) bz[q[++r]=en[i]]=true;}}}return dis[n]<=T;
}
inline bool getans(LL val)
{memset(dis,60,sizeof(dis));memset(bz,false,sizeof(bz));int l=dis[1]=0,r=q[1]=1;while(l<r){int x=q[++l];bz[x]=false;for(int i=first[x];i;i=nex[i]){LL vv=w[i]-val<0?0:w[i]-val;if(dis[x]+vv<dis[en[i]]){dis[en[i]]=dis[x]+vv;if(!bz[en[i]]) bz[q[++r]=en[i]]=true;}}}
}
int main()
{freopen("magic.in","r",stdin);freopen("magic.out","w",stdout);n=read(),m=read();scanf("%lld",&T);for(int i=1;i<=n;i++) a[i]=read();miu[1]=pre[1]=1;for(int i=2;i<N;i++){if(!bz[i]){f[++f[0]]=i;miu[i]=-1;}for(int j=1;j<=f[0] && i*f[j]<N;j++){bz[i*f[j]]=true;if(i%f[j]==0){miu[i*f[j]]=0;break;}miu[i*f[j]]=-miu[i];}pre[i]=pre[i-1]+miu[i]*i;}for(int i=1;i<=m;i++){int x=read(),y=read();int vx=a[x],vy=a[y];if(vx>vy) swap(vx,vy);LL sum=0;for(int j=1,p;j<=vx;j=p+1){p=min(vx/(vx/j),vy/(vy/j));int xx=vx/p,yy=vy/p;sum+=(LL)xx*yy*(xx+yy+2)/2*(pre[p]-pre[j-1]);}insert(x,y,sum);insert(y,x,sum);}LL l=0,r=1e18;while(l<=r){LL mid=l+r>>1;if(check(mid)){ans=mid;r=mid-1;}else l=mid+1;}getans(ans);printf("%lld %lld",ans,dis[n]);return 0;
}
JZOJ 5701. 【gdoi2018 day2】第一题 谈笑风生(magic)相关推荐
- LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告
LOJ#6103. 「2017 山东二轮集训 Day2」第一题 解题报告 前置知识:闭区间上的连续函数的零点存在性定理: 我们定义这样的函数: 定义域为 [ l , r ] ∩ Z [l,r]\cap ...
- 四川大学线下编程比赛第一题:数字填充
四川大学线下编程比赛第一题:数字填充 公布公司: 有 效 期: CSDN 2014-09-27至2015-09-26 难 度 等 级: 答 题 时 长: 编程语言要求: 120分钟 C C++ Jav ...
- 开篇第一题:经典中的经典!
开篇第一题:经典中的经典! --评<编程之美> 原贴地址:http://www.douban.com/review/2130819/ 应该 ...
- /* * 编程第一题(20分): 1+(1+2)+(1+2+3)+……+(1+2+3+……+98+99+100) */
题目: /* 编程第一题(20分): 1+(1+2)+(1+2+3)+--+(1+2+3+--+98+99+100) */ 我是用的java做的 class One {public static vo ...
- 2021年人工神经网络第四次作业-第一题:LeNet对于水果与动物进行分类
简 介: 对于有五种动物和五中水果组成的FAMNIST数据集合的图像分类问题进行了测试.本文主要是集中在前期的数据库的准备和网络的构建方面.对于网络的详细测试参见在 对于FAMNIST中的十种动物和水 ...
- 2021年春季学期-信号与系统-第一次作业参考答案-第一题
本文是: 2021年春季学期-信号与系统-第一次作业参考答案 的参考答案. ▌第一题 1.绘出下列各信号的波形: 注:u(t),u[n]u\left( t \right),\,\,u\left[ ...
- 2020年人工神经网络第二次作业-参考答案第一题
如下是 2020年人工神经网络第二次作业 中第一题的参考答案. ➤01 第一题参考答案 1.题目分析 (1) 已知条件 本题中的建立的是一个由两个竞争节点组成的竞争网络.竞争层的神经元和五个训练样本都 ...
- 2014年百度之星资格赛第一题Energy Conversion
2014年百度之星资格赛第一题Energy Conversion Problem Description 魔法师百小度也有遇到难题的时候-- 如今,百小度正在一个古老的石门面前,石门上有一段古老的魔法 ...
- matlab_exercise(4)----第一题
第二次作业-----第一题 题目: 1.某零售店有9种商品的单件进价(元).售价(元)及一周的销量如下表, 问哪种商品的单件利润最大,哪种商品的单件利润最小: 按收入由小到大,列出所有商品及其收入: ...
最新文章
- 1102: 火车票退票费计算(函数专题)
- tar php启动,安装php过程(FastCGI模式)
- 类继承、组合和抽象类
- 基于Xml 的IOC 容器-解析配置文件路径
- 【区块链:超级账本】Win10 Hyperledger环境搭建
- 猫叫人醒老鼠跑 C#的委托及事件
- tina中信号带宽_关于通频带,3dB带宽,三阶截点和1dB压缩点,截止频率,频率范围,带宽,特征频率(中心频率),截止频率和增益(db)...
- 别用Excel做数据可视化了!这款报表工具不比它香100倍?
- 如何停止CSS3的动画?
- 效果过度transition:all
- print_r与var_dump
- 求最小公倍数的两种算法(最大公约数的三种算法)
- 医院时钟系统,NTP子钟,网络子母钟系统,ntp子母钟,网络子母钟——为您的系统保驾护航
- zipoutputstream 进行解压缩时winrar提示:不可预料的压缩文件末端
- STM32CUBE+自平衡车实践篇3.4-STM32cueb配置编码器+车轮速度测量代码实现
- 致刚就业迷茫的你和寄语大学毕业生--技术读者
- jmeter参数化时常用随机函数
- Android ART 即时 (JIT) 编译器详解
- Java+Swing+Mysql学生宿舍管理系统
- FastRule: Efficient Flow Entry Updates for TCAM-based OpenFlow Switches(二)
热门文章
- “熊猫烧香”式的病毒营销
- keras入门之手写字识别python代码
- Python学习笔记:输入和输出
- 梯度下降法,牛顿法,高斯-牛顿迭代法,附代码实现
- Linux配置启动挂载:fstab文件详解
- 求某类型变量的大小(是否使用sizeof)
- android textwatcher 延时,Java-防止两次在android的textwatcher中运行
- improve php,解析提高PHP执行效率
- 云炬Android开发笔记 14 个人中心、图片裁剪、图片上传、收货地址、消息推送、权限管理等功能开发与一键式封装
- 帝国CMS后台前台上传大小和类型限制的解决方法!