解题:NOI 2014 购票
观察一下部分分,我们发现链上的部分分是这样一个DP:
$dp[i]=min(dp[i],dp[j]+dis(i,j)*p[i]+q[i])(dis(i,j)<=lim[i]\&\&j∈anc(i))$
对于可以对$i$转移的两个位置$j$和$k$,假设$dep[j]>dep[k]$且$j$比$k$优,那么倒腾一下式子
$dp[j]+dis(i,j)*p[i]+q[i]<dp[k]+dis(i,k)*p[i]+q[i]$
$dp[j]-dp[k]<(dis(i,k)-dis(i,j))*p[i]$
$\frac{dp[j]-dp[k]}{dis(i,k)-dis(i,j)}<p[i]$
因为$dis$是单调的,这个东西可以使用斜率优化,因为$p[i]$不单调每次需要二分来转移
然后问题来了,现在不是棵树,如果提出来每条链来做是O(叶子数*len)的,会被扫帚图卡掉,于是有了各种优化来做这道题:
Sol1:用轻重链剖分优化,直接以一个log的代价把整条链拼出来,再用一个log的数据结构维护,复杂度$O(n\log^3 n)$
Sol2:用可持久化数据结构维护单调队列或者用待撤销的二进制分组,利用上面一段已经处理好的链分别处理每个叶子,只需要一个log,复杂度$O(n\log^2 n)$
Sol3(我写的这个):不用数据结构维护,用点分治的方法,每次把重心和它子树外的部分递归处理,然后DFS重心的子树,子树里的节点按向上延伸后的深度排序后DP,之后再处理每一棵子树。排序和DP的log是并列的,复杂度$O(n\log^2 n)$
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,inf=1e9;
int n,t,c,cnt,top,tpp,tsiz,maxx;
int fth[N],p[N],noww[N],goal[N],siz[N],vis[N],stk[N],sta[N];
long long len[N],val[N],dis[N],pr1[N],pr2[N],lim[N],dp[N],rd;
bool cmp(int a,int b)
{
return dis[a]-lim[a]>dis[b]-lim[b];
}
double Slope(int a,int b)
{
return (double)(dp[b]-dp[a])/(double)(dis[b]-dis[a]);
}
void Link(int f,int t,long long v)
{
noww[++cnt]=p[f],p[f]=cnt;
goal[cnt]=t,val[cnt]=v;
}
void Getdis(int nde)
{
for(int i=p[nde];i;i=noww[i])
dis[goal[i]]=dis[nde]+val[i],Getdis(goal[i]);
}
void Mark(int nde,int sze)
{
siz[nde]=; int tmp=;
for(int i=p[nde];i;i=noww[i])
if(!vis[goal[i]])
{
Mark(goal[i],sze);
siz[nde]+=siz[goal[i]];
tmp=max(tmp,siz[goal[i]]);
}
tmp=max(tmp,sze-siz[nde]);
if(tmp<=maxx) maxx=tmp,c=nde;
}
void DFS(int nde)
{
stk[++top]=nde;
for(int i=p[nde];i;i=noww[i])
if(!vis[goal[i]]) DFS(goal[i]);
}
void DP(int nde,int anc)
{
for(int i=;i<=top;i++)
{
int nod=stk[i];
while(nde!=fth[anc]&&dis[nod]-dis[nde]<=lim[nod])
{
while(tpp>=&&Slope(sta[tpp],nde)>=Slope(sta[tpp-],sta[tpp]))
tpp--; sta[++tpp]=nde,nde=fth[nde];
}
if(tpp)
{
int l=,r=tpp,best;
while(l<=r)
{
int mid=(l+r)/;
double s=(mid==tpp)?-inf:Slope(sta[mid],sta[mid+]);
if(s<=pr1[nod]) r=mid-,best=mid; else l=mid+;
}
best=sta[best],dp[nod]=min(dp[nod],dp[best]+(dis[nod]-dis[best])*pr1[nod]+pr2[nod]);
}
}
}
void PDC(int nde,int sze)
{
if(sze<=) return;
maxx=inf,Mark(nde,sze); int hc=c;
for(int i=p[hc];i;i=noww[i])
vis[goal[i]]=true,sze-=siz[goal[i]];
PDC(nde,sze),top=;
for(int i=p[hc];i;i=noww[i]) DFS(goal[i]);
sort(stk+,stk++top,cmp),tpp=,DP(hc,nde);
for(int i=p[hc];i;i=noww[i]) PDC(goal[i],siz[goal[i]]);
}
int main()
{
scanf("%d%d",&n,&t);
for(int i=;i<=n;i++)
{
scanf("%d%lld",&fth[i],&rd),Link(fth[i],i,rd);
scanf("%lld%lld%lld",&pr1[i],&pr2[i],&lim[i]),dp[i]=1e18;
}
Getdis(),PDC(,n);
for(int i=;i<=n;i++) printf("%lld\n",dp[i]);
return ;
}
解题:NOI 2014 购票的更多相关文章
- BZOJ 3672 NOI 2014 购票
题面 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市 ...
- [luogu P2375] [NOI 2014] 动物园
[luogu P2375] [NOI 2014] 动物园 题目描述 近日,园长发现动物园中好吃懒做的动物越来越多了.例如企鹅,只会卖萌向游客要吃的.为了整治动物园的不良风气,让动物们凭自己的真才实学向 ...
- 【BZOJ 3672】【UOJ #7】【NOI 2014】购票
http://www.lydsy.com/JudgeOnline/problem.php?id=3672 http://uoj.ac/problem/7 链上的情况可以用斜率优化dp.树上用斜率优化d ...
- 解题:NOI 2014 随机数生成器
题面 为什么NOI2014有模拟题=.=??? 按题意把序列生成出来之后,对每一行维护一个能取到的最左侧和能取到的最右侧.从小到大$O(n^2)$枚举数字看看能否填入,能填入则暴力$O(n)$更新信息 ...
- 解题:NOI 2014 动物园
题面 其实好像并不难,因为猫老师(应该是猫老师吧,还是LX大佬?)有一句话让我印象深刻:“包的(border)的包的还是包的”=.= 统计个数不就是统计长度么,然后根据上面那句话,当$nxt$长度大于 ...
- [NOI 2014]魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- [NOI 2014]做题记录
[NOI2014]起床困难综合症 按位贪心 #include <algorithm> #include <iostream> #include <cstring> ...
- NOI 2014 感想
NOI2014结束了,我卡线登上了领奖台... 这是我第一次NOI,我觉得我收获了很多东西: 1.考前心态不重要,重要的是实力 真正考试的时候是顾不得想其他事情的 2.测试数据是人出的!不是随机的!不 ...
- NOI 2014简要题解
Day 1.Problem A. 起床困难综合症 100分做法: 把数字看成二进制数.对于初始攻击力.我们将其拆成32位,并求出每一位为0和1时经过全部防御门之后分别得到的数字.然后就是按位贪心了,我 ...
随机推荐
- Webstorm使用时发生Page 'http://localhost:63340/n…tok/css/bootstrap.css.map' requested without authorization, you can copy URL and open it in browser to trust it.
在使用webstorm编辑器开发时候,点击4处发生以下错误: Page 'http://localhost:63340/n…tok/css/bootstrap.css.map' requested w ...
- chattr和lsattr命令详解
基础命令学习目录首页 原文链接:http://www.ha97.com/5172.html PS:有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chat ...
- [linux] LVM原磁盘扩容(非增加磁盘)
阿里云机器,ECS运行时磁盘由300G扩容到500,重启机器生效后登录.可以看到/data目录总大小300G,/dev/vdb已经扩容到500G. [root@HD1g-elasticsearch2 ...
- ./configure的含义
在实践安装nginx的时候,不知道./configure是什么意思,这里特地记录一下. 在linux中./代表当前目录,属于相对路径../代表上一级目录,属于相对路径/代表根目录,/开头的文件都是绝对 ...
- 微信公众号开发笔记1(nodejs开发)
本篇记录了微信公众号开发的一些笔记 一.微信服务器与我们服务器的交流 微信开发者拥有自己的服务器,在我们服务器上可以与微信服务器进行交流.既然可以交流,那就必定需要前提条件(微信认证),也就是说,只有 ...
- pairwork(黄敬博12061156和黄伟龙12061172)
结对编程: 结对编程的优缺点: 优点: 1.相互督促,共同为了完成目标而努力: 2.节省时间,通过将疑难问题分开解决,共同讨论,实现了更高效的时间利用率: 3.能力互补,提高代码的质量,同时也提高了测 ...
- 第二阶段Sprint冲刺会议8
进展:重新规划主界面,把视频录制暂放到主页面里,先实现功能,视频提醒后期再做.
- 第二阶段Sprint冲刺会议7
进展:试着把视频录制功能加到时间提醒中,但是整合没有成功,今天没有进展.
- 23_IO_第23天(字节流、字符流)_讲义
今日内容介绍 1.字节流 2.字符流 01输入和输出 * A:输入和输出 * a: 参照物 * 到底是输入还是输出,都是以Java程序为参照 * b: Output * 把内存中的数据存储到持久化设备 ...
- 【Leetcode】86. Partition List
Question: Given a linked list and a value x, partition it such that all nodes less than x come befor ...