[BZOJ3672][UOJ#7][NOI2014]购票
[BZOJ3672][UOJ#7][NOI2014]购票
试题描述
输入
第 1 行包含2个非负整数 n,t,分别表示城市的个数和数据类型(其意义将在后面提到)。输入文件的第 2 到 n 行,每行描述一个除SZ之外的城市。其中第 v 行包含 5 个非负整数 f_v,s_v,p_v,q_v,l_v,分别表示城市 v 的父亲城市,它到父亲城市道路的长度,票价的两个参数和距离限制。请注意:输入不包含编号为 1 的SZ市,第 2 行到第 n 行分别描述的是城市 2 到城市 n。
输出
输出包含 n-1 行,每行包含一个整数。其中第 v 行表示从城市 v+1 出发,到达SZ市最少的购票费用。同样请注意:输出不包含编号为 1 的SZ市。
输入示例1
输出示例1
输入示例2
传送门(点击下载)
输出示例2
数据规模及约定
对于所有测试数据,保证 0≤pv≤106,0≤qv≤1012,1≤fv<v;保证 0<sv≤lv≤2×1011,且任意城市到SZ市的总路程长度不超过 2×1011。
输入的 t 表示数据类型,0≤t<4,其中:
当 t=0 或 2 时,对输入的所有城市 v,都有 fv=v-1,即所有城市构成一个以SZ市为终点的链;
当 t=0 或 1 时,对输入的所有城市 v,都有 lv=2×1011,即没有移动的距离限制,每个城市都能到达它的所有祖先;
当 t=3 时,数据没有特殊性质。
n=2×10^5
题解
借着此题学了学有根树分治
首先不难想出一个dp,设f(i)表示节点 i 到节点 1 所需的最小花费,有 f(i) = min{ f(j) + d(i ~ j) * p(i) + q(i) | j 为 i 祖先 & d(i ~ j) <= l(i) },其中d(i ~ j)表示节点 i 到 j 的距离,p, q, l 的意义见题目描述。
还是基本的思想,把d(i ~ j)拆开,变成dep(i) - dep(j)(dep(i)表示节点 i 到根的距离),于是上述式子转化成 f(i) - dep[i] * p(i) - q(i) = min{ f(j) + p(i) * dep(j) | 条件略 },可以用分治把它转化成一个序列问题,有一定顺序后就可以维护下凸壳了。
分治的思想是:对于子树u,找到其重心rt,分治处理u所在的以rt为根的子树,然后用u到rt这一条链上的信息更新以rt为根的其他子树上节点的信息。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;
#define LL long long
#define LD double const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *tail;
inline char Getchar() {
if(Head == tail) {
int l = fread(buffer, 1, BufferSize, stdin);
tail = (Head = buffer) + l;
}
return *Head++;
}
LL read() {
LL x = 0, f = 1; char c = Getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
return x * f;
} #define maxn 200010
#define maxm 400010
#define oo 1ll << 60
int n, m, head[maxn], next[maxm], to[maxm], fa[maxn];
LL dep[maxn], f[maxn], p[maxn], q[maxn], l[maxn]; void AddEdge(int a, int b) {
to[++m] = b; next[m] = head[a]; head[a] = m;
swap(a, b);
to[++m] = b; next[m] = head[a]; head[a] = m;
return ;
} int root, size, siz[maxn], g[maxn];
bool vis[maxn];
void getroot(int u, int pa) {
siz[u] = 1; int maxs = 0;
for(int e = head[u]; e; e = next[e]) if(!vis[to[e]] && to[e] != pa) {
getroot(to[e], u);
siz[u] += siz[to[e]];
maxs = max(maxs, siz[to[e]]);
}
g[u] = max(maxs, size - siz[u]);
if(g[u] < g[root]) root = u;
return ;
} int A[maxn], cnt;
void dfs(int u, int pa) {
A[++cnt] = u;
for(int e = head[u]; e; e = next[e]) if(!vis[to[e]] && to[e] != pa)
dfs(to[e], u);
return ;
}
bool cmp(int i, int j) { return dep[i] - l[i] > dep[j] - l[j]; }
LD slop(int i, int j) { return (LD)(f[i] - f[j]) / (dep[i] - dep[j]); }
int Q[maxn];
void solve(int u) {
g[root = 0] = n+1; getroot(u, 0);
int ni = root, rt = root; vis[root] = 1;
if(!vis[u]) size = siz[u] - siz[rt], solve(u);
// printf("%d %d\n", u, ni);
cnt = 0;
for(int e = head[ni]; e; e = next[e]) if(!vis[to[e]]) dfs(to[e], ni);
sort(A + 1, A + cnt + 1, cmp);
for(int i = fa[ni]; i != fa[u] && dep[i] >= dep[ni] - l[ni]; i = fa[i])
f[ni] = min(f[ni], f[i] + (dep[ni] - dep[i]) * p[ni] + q[ni]);
for(int i = 1, r = 0; i <= cnt; i++) {
for(; ni != fa[u] && dep[ni] >= dep[A[i]] - l[A[i]]; ni = fa[ni]) {
while(r > 1 && slop(Q[r-1], Q[r]) <= slop(Q[r], ni)) r--;
Q[++r] = ni;
}
int L = 1, R = r + 1;
while(R - L > 1) {
int M = L + R >> 1;
if(M == 1 || slop(Q[M-1], Q[M]) >= (LD)p[A[i]]) L = M;
else R = M;
}
if(L < R) f[A[i]] = min(f[A[i]], f[Q[L]] + (dep[A[i]] - dep[Q[L]]) * p[A[i]] + q[A[i]]);
}
for(int e = head[rt]; e; e = next[e]) if(!vis[to[e]]) {
size = siz[to[e]]; solve(to[e]);
}
return ;
} int main() {
// freopen("ex_ticket2.in", "r", stdin);
// freopen("out.out", "w", stdout);
n = read(); read();
f[1] = 0;
for(int i = 2; i <= n; i++) {
f[i] = oo;
fa[i] = read(); AddEdge(fa[i], i);
dep[i] = dep[fa[i]] + read();
p[i] = read(); q[i] = read(); l[i] = read();
} size = n;
solve(1); for(int i = 2; i <= n; i++) printf("%lld\n", f[i]); return 0;
}
[BZOJ3672][UOJ#7][NOI2014]购票的更多相关文章
- UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP
[NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...
- UOJ #7 NOI2014购票(点分治+cdq分治+斜率优化+动态规划)
重写一遍很久以前写过的题. 考虑链上的问题.容易想到设f[i]为i到1的最少购票费用,转移有f[i]=min{f[j]+(dep[i]-dep[j])*p[i]+q[i]} (dep[i]-dep[j ...
- 【bzoj3672&&uoj7】[Noi2014]购票
*题目描述: 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的父亲用道路 ...
- UOJ 7 NOI2014 购票
题意:给一棵树计算一下各个点在距离限制下以一定的费用公式通过不停地到祖先最后到达一号点的最小花费. 第一种做法:线段树维护带修凸壳.显然的,这个公式计算是p*x+q 所以肯定和斜率有关系.然后这题的d ...
- 【BZOJ3672】【NOI2014】购票(线段树,斜率优化,动态规划)
[BZOJ3672][NOI2014]购票(线段树,斜率优化,动态规划) 题解 首先考虑\(dp\)的方程,设\(f[i]\)表示\(i\)的最优值 很明显的转移\(f[i]=min(f[j]+(de ...
- 【BZOJ3672】[Noi2014]购票 树分治+斜率优化
[BZOJ3672][Noi2014]购票 Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. ...
- bzoj千题计划251:bzoj3672: [Noi2014]购票
http://www.lydsy.com/JudgeOnline/problem.php?id=3672 法一:线段树维护可持久化单调队列维护凸包 斜率优化DP 设dp[i] 表示i号点到根节点的最少 ...
- [BZOJ3672][Noi2014]购票 斜率优化+点分治+cdq分治
3672: [Noi2014]购票 Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1749 Solved: 885[Submit][Status][ ...
- [BZOJ3671][UOJ#6][NOI2014]随机数生成器
[BZOJ3671][UOJ#6][NOI2014]随机数生成器 试题描述 小H最近在研究随机算法.随机算法往往需要通过调用随机数生成函数(例如Pascal中的random和C/C++中的rand)来 ...
随机推荐
- CSharpThinking---C#版本总结(附加三)
C#版本总结: 日期 框架.net Visual Studio C# CLR 2002.2 1.0 2002 1.0 1.0 2003.4 1.1 2003 1.2 1.1 2005.11 2. ...
- 第四十六课:MVC和MVVM的开发区别
实现MVC的目的就是为了让M和V相分离.前端的MVC无法做到View和Model的相分离,而MVVM可以. 我们先来看一个用MVC模式开发的经典例子:(一定要深入了解这种开发的思想,而不是看懂代码) ...
- angular-scope.assign
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- final和static
/* final修饰符 1. final修饰的类不能被继承,没有子类 2. final修饰的方法不能被子类覆盖 3. final修饰的变量表示常量,只能被赋值一次 4. final 修饰 ...
- 新建URL,cookie技术
假如用户禁止了cookie,怎么用session技术 //在这里访问一下session request.getSession(); //这里注意的是 要使用一下session while(iterat ...
- javascript this 详解
前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的设计模式来实现面向对象的编程,其中this ...
- iOS不得姐项目--appearance的妙用,再一次设置导航栏返回按钮,导航栏左右按钮的封装(巧用分类)
一.UI_APPEARANCE_SELECTOR 彩票项目中appearance的用法一直没有搞明白,这次通过第二个项目中老师的讲解,更深一层次的了解到了很多关于appearance的作用以及使用方法 ...
- struts2中把action中的值传递到jsp页面的例子
例子: RegistAction的代码: package com.wss.action; import javax.servlet.http.HttpServletRequest; import or ...
- MyEclipse护眼模式、字体大小的调整
1.Eclipse改变背景颜色 Windows menu --> Preference General -> Editors -> Text Editors(click), 在底部 ...
- BZOJ solve 100 纪念
按照xiaoyimi立下的flag是不是该去表白啦--可惜并没有妹子