【XSY1476】平凡之路 斜率优化DP
题目大意
有\(n\)个格子,一开始你在\(1\)号格子。每次你只能往编号更大的格子走。从第\(i\)个格子走到第\(j\)个格子的代价是\(a_i+a_j\times(j-i)\times m\)
\(a_i\)为与\(i\)互质且不大于\(i\)的正整数的个数。
\(n\leq 1000000\)
题解
显然\(a_i=\varphi(i)\)。
如果\(j<k\)且\(j\)比\(k\)优,那么
f_j+a_j+a_i\times (i-j)\times m&<f_k+a_k+a_i\times (i-k)\times m\\
f_j+a_j+a_iim-a_ijm&<f_k+a_k+a_iim-a_ikm\\
f_j+a_j-a_ijm&<f_k+a_k-a_ikm\\
f_j+a_j-f_k-a_k&<a_ijm-a_ikm\\
\frac{f_j-f_k+a_j-a_k}{j-k}&>a_im
\end{align}
\]
这告诉我们要维护一个斜率递增的栈。
这道题\(a_i\)不像其他题一样是单调递增的,所以要把下凸壳上所有的点保存下来,每次二分找到最优的点。
时间复杂度:\(O(n\log n)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<cmath>
#include<functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
void sort(int &a,int &b)
{
if(a>b)
swap(a,b);
}
void open(const char *s)
{
#ifndef ONLINE_JUDGE
char str[100];
sprintf(str,"%s.in",s);
freopen(str,"r",stdin);
sprintf(str,"%s.out",s);
freopen(str,"w",stdout);
#endif
}
int rd()
{
int s=0,c;
while((c=getchar())<'0'||c>'9');
do
{
s=s*10+c-'0';
}
while((c=getchar())>='0'&&c<='9');
return s;
}
int upmin(int &a,int b)
{
if(b<a)
{
a=b;
return 1;
}
return 0;
}
int upmax(int &a,int b)
{
if(b>a)
{
a=b;
return 1;
}
return 0;
}
int b[1000010];
int pri[1000010];
int cnt;
int phi[1000010];
ll f[1000010];
//ll g[1000010];
int q[1000010];
//int from[1000010];
ll gety(int x)
{
return f[x]+phi[x];
}
int n,m;
ll calc(int x,int y)
{
return f[x]+phi[x]+phi[y]*ll(y-x)*m;
}
int main()
{
open("pfzr");
scanf("%d%d",&n,&m);
int i,j;
phi[1]=1;
for(i=2;i<=n;i++)
{
if(!b[i])
{
pri[++cnt]=i;
phi[i]=i-1;
}
for(j=1;j<=cnt&&i*pri[j]<=n;j++)
{
b[i*pri[j]]=1;
if(i%pri[j]==0)
{
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
memset(f,0x7f,sizeof f);
// memset(g,0x7f,sizeof g);
// g[1]=0;
f[1]=0;
// for(i=2;i<=n;i++)
// for(j=1;j<i;j++)
// if(g[j]+phi[j]+ll(phi[i])*(i-j)*m<g[i])
// {
// g[i]=g[j]+phi[j]+ll(phi[i])*(i-j)*m;
// from[i]=j;
// }
int t=0;
q[++t]=1;
for(i=2;i<=n;i++)
{
int l=1,r=t;
while(l<r)
{
int mid=(l+r)>>1;
if(gety(q[mid])-gety(q[mid+1])<ll(q[mid]-q[mid+1])*phi[i]*m)
r=mid;
else
l=mid+1;
}
f[i]=f[q[l]]+phi[q[l]]+ll(phi[i])*(i-q[l])*m;
while(t>=2&&(gety(q[t-1])-gety(q[t]))*(q[t]-i)>(gety(q[t])-gety(i))*(q[t-1]-q[t]))
t--;
while(t>=1&&gety(q[t])-gety(i)>0)
t--;
q[++t]=i;
}
printf("%lld\n",f[n]);
return 0;
}
【XSY1476】平凡之路 斜率优化DP的更多相关文章
- bzoj-4518 4518: [Sdoi2016]征途(斜率优化dp)
题目链接: 4518: [Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地 ...
- bzoj4518[Sdoi2016]征途 斜率优化dp
4518: [Sdoi2016]征途 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1657 Solved: 915[Submit][Status] ...
- 【转】斜率优化DP和四边形不等式优化DP整理
(自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...
- CodeForces 311 B Cats Transport 斜率优化DP
题目传送门 题意:现在有n座山峰,现在 i-1 与 i 座山峰有 di长的路,现在有m个宠物, 分别在hi座山峰,第ti秒之后可以被带走,现在有p个人,每个人会从1号山峰走到n号山峰,速度1m/s.现 ...
- 洛谷 P4072 [SDOI2016]征途 斜率优化DP
洛谷 P4072 [SDOI2016]征途 斜率优化DP 题目描述 \(Pine\) 开始了从 \(S\) 地到 \(T\) 地的征途. 从\(S\)地到\(T\)地的路可以划分成 \(n\) 段,相 ...
- CF-311B Cats Transport(斜率优化DP)
题目链接 题目描述 小S是农场主,他养了 \(M\)只猫,雇了 \(P\) 位饲养员. 农场中有一条笔直的路,路边有 \(N\) 座山,从 \(1\) 到 \(N\)编号. 第 \(i\) 座山与第 ...
- bzoj-1096 1096: [ZJOI2007]仓库建设(斜率优化dp)
题目链接: 1096: [ZJOI2007]仓库建设 Description L公司有N个工厂,由高到底分布在一座山上.如图所示,工厂1在山顶,工厂N在山脚.由于这座山处于高原内陆地区(干燥少雨),L ...
- [BZOJ3156]防御准备(斜率优化DP)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3156 分析: 简单的斜率优化DP
- 【BZOJ-1096】仓库建设 斜率优化DP
1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3719 Solved: 1633[Submit][Stat ...
随机推荐
- Appium+Python3+iOS定位元素
前言: 最近在做IOS自动化测试,IOS的Appium环境都配置OK,执行起来真的慢,慢到怀疑人生,那么今天就来总结一下IOS定位方式和各个定位方式的速度排序. 据我观察,按查找元素的顺序速度,从快到 ...
- 周末时间学习Linux
大家都是如何度过周末时光的呢?好多人都认为一周的工作后要好好休息下,于是在家疯狂的补觉,刷剧,打游戏,自我觉得很是正常,工作几天了,休息下不是当然嘛.是的,休息下很正常,但是把周末的时光都用到这些东西 ...
- Day14 Python基础之os/sys/hashlib模块(十二)
os模块 os.getcwd() #获取当前工作路径 os.chdir(‘dirname1/dirname2/dirname3’) #改变当前脚本的工作路径,相当于cmd下的cd os.makedi ...
- python中类方法,实例方法,静态方法的作用和区别
Python中至少有三种比较常见的方法类型,即实例方法,类方法.静态方法.它们是如何定义的呢?如何调用的呢?它们又有何区别和作用呢?且看下文. 首先,这三种方法都定义在类中.下面我先简单说一下怎么 ...
- 解决ImportError: cannot import name 'webdriver' from 'selenium' (C:\Users\Mr.Su\PycharmProjects\***\venv\selenium.py)
报错信息如下图所示: 解决方案:将项目根目录下的自己创建的selenium.py文件重命名.
- C#复习笔记(3)--C#2:解决C#1的问题(进入快速通道的委托)
委托 前言:C#1中就已经有了委托的概念,但是其繁杂的用法并没有引起开发者太多的关注,在C#2中,进行了一些编译器上的优化,可以用匿名方法来创建一个委托.同时,还支持的方法组和委托的转换.顺便的,C# ...
- Java Integer 与 int 深刻理解
今天在做Object 自动转为Integer 类型之后的判断,遇到一个不理解的点,当数值超过127之后,两个数值相同的Object 对象用 == 判断的结果是false. Object a = 128 ...
- [转帖]批处理-For详解
批处理-For详解 https://www.cnblogs.com/DswCnblog/p/5435300.html for 循环的写法 感觉非常好. 今天下午的时候简单测试了下. 多学习提高 非常重 ...
- 原生JS实现增加删除class
<!DOCTYPE html> <html> <head> <style type="text/css"> .night-mode{ ...
- 取得数据表中前N条记录,某列重复的话只取第一条记录
项目需要筛选出不重复数据,以前没有做过,第一反应就是利用distinct处理,但是弄了好久也没搞出来,大家有知道的望告知下. 这次筛选没有使用distinct ,是利用group by ,利用id为唯 ...