解题: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时经过全部防御门之后分别得到的数字.然后就是按位贪心了,我 ...
随机推荐
- gcc 与 g++的区分较
一:gcc与g++比较 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序:后缀为.cpp的,两者都会认为 ...
- 机器学习之k-最近邻(kNN)算法
一.kNN(k-nearest neighbor)算法原理 事物都遵循物以类聚的思想,即有相同特性的事物在特征空间分布上会靠得更近,所以kNN的思路是:一个样本在特征空间中k个靠的最近的样本中,大多数 ...
- jobs命令详解
基础命令学习目录首页 在用管理员执行一个命令后,用Ctrl+Z把命令转移到了后台.导致无法退出root的. 输入命令:exit终端显示:There are stopped jobs. 解决方法:方法一 ...
- 图解Raid5数据存储的原理
- “Hello World!”团队第六周的第三次会议
今天是我们团队“Hello World!”团队第六周召开的第三次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 八.代码 一 ...
- 实验三 Java猜数字游戏开发
课程:Java实验 班级:201352 姓名:程涵 学号:20135210 成绩: 指导教师:娄佳鹏 实验日期:15.06.03 实验密级: ...
- 使用python快速搭建web服务器
命令:python -m SimpleHTTPServer 8088 参考:https://www.cnblogs.com/harry-xiaojun/p/6739003.html https://w ...
- ACM Shenyang Onsite 2016 题目
A. Thickest Burger 1000ms 262144K ACM ICPC is launching a thick burger. The thickness (or the heig ...
- Node.js记录
在智能社上听了一些关于node.js的视频,总结一小部分内容,都是总结老师讲的知识点,并且也是在不断学习的过程,所以会不断更新.也是为了怕自己遗忘一些知识点,同时现今没有什么项目可以让我去真正实践,这 ...
- iOS- 多线程中如何去保证线程安全
一.前言 前段时间看了几个开源项目,发现他们保持线程同步的方式各不相同,有@synchronized.NSLock.dispatch_semaphore.NSCondition.pthread_mut ...