最大的收获就是题目所说。

deal(s) : 处理节点s所在块的问题,并保证:

  1、s是该块中最靠近根节点的点,没有之一。

  2、s所在块到根节点的路径上的点全都用来更新过了s所在块的所有节点。

然后步骤是:

  1、找s所在块的重心c。

  2、如果s就是c,那么用c更新当前块的所有节点,然后“删除c”,递归处理新产生的子块。

  3、否则,删除c,deal(s),用c到s的路径(不包括c,包括s)更新c除了s子块的其他子块以及c,然后再用c去更新一次。

  4、递归处理其它子块。

 #include <cstdio>
#include <cassert>
#include <cstring>
#include <algorithm>
#define N 200010
#define M N<<1
#define fill(arr,lf,rg,v) memset(arr+lf,v,sizeof(arr[0])*(rg-lf+1))
using namespace std; typedef long long dnt;
struct Vector {
dnt x, y;
Vector(){}
Vector( dnt x, dnt y ):x(x),y(y){}
Vector operator+( const Vector &o ) const { return Vector(x+o.x,y+o.y); }
Vector operator-( const Vector &o ) const { return Vector(x-o.x,y-o.y); }
double operator^( const Vector &o ) const { return (double)x*o.y-(double)y*o.x; }
};
typedef Vector Point;
bool onleft( const Point &a, const Point &b, const Point &c ) {
return ((b-a)^(c-a)) >= 0.0;
}
struct Convex {
Point stk[N];
int top;
void init() {
top=-;
}
inline void append( const Point &p ) {
while( top> && onleft(stk[top-],stk[top],p) ) top--;
stk[++top] = p;
}
const Point& query( dnt k ) {
int lf=;
int rg=top;
if( lf==rg ) return stk[top];
assert(k*(stk[lf].x-stk[lf+].x)>=);
if( k*(stk[lf].x-stk[lf+].x) >= (stk[lf].y-stk[lf+].y) )
return stk[lf];
assert(k*(stk[rg-].x-stk[rg].x)>=);
if( k*(stk[rg-].x-stk[rg].x) <= (stk[rg-].y-stk[rg].y) )
return stk[rg];
lf++;
rg--;
while( lf<rg ) {
int mid=(lf+rg)>>;
assert(k*(stk[mid].x-stk[mid+].x)>=);
if( k*(stk[mid].x-stk[mid+].x) > (stk[mid].y-stk[mid+].y) )
rg=mid;
else
lf=mid+;
}
return stk[lf];
}
}; int n, case_type;
int head[N], next[M], dest[M], etot;
dnt wp[N], wq[N], lim[N], ws[M];
int anc[N], fat[N], vis[N], siz[N], bac[N];
dnt dep[N], dp[N];
int qu[N], bg, ed;
Convex convex; void adde( int u, int v, dnt s ) {
etot++;
dest[etot] = v;
next[etot] = head[u];
ws[etot] = s;
head[u] = etot;
}
void bfs( int s ) {
qu[bg=ed=] = s;
anc[s] = ;
dep[s] = ;
while( bg<=ed ) {
int u=qu[bg++];
for( register int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==anc[u] ) continue;
qu[++ed] = v;
anc[v] = u;
dep[v] = dep[u]+ws[t];
}
}
}
int getc( int s ) {
qu[bg=ed=] = s;
fat[s] = ;
bac[s] = ;
siz[s] = ;
while( bg<=ed ) {
int u=qu[bg++];
for( register int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( vis[v] || v==fat[u] ) continue;
qu[++ed] = v;
fat[v] = u;
bac[v] = ;
siz[v] = ;
}
}
int c = ;
for( register int i=ed; i>=; i-- ) {
int u=qu[i];
siz[u]++;
if( fat[u] ) {
int f=fat[u];
siz[f]+=siz[u];
if( siz[u]>bac[f] ) bac[f]=siz[u];
}
}
for( register int i=; i<=ed; i++ ) {
int u=qu[i];
if( bac[u]<siz[s]-siz[u] ) bac[u]=siz[s]-siz[u];
if( !c || bac[u]<bac[c] ) c=u;
}
//fprintf( stderr, "%d\n", c );
return c;
}
void flood( int s ) {
qu[bg=ed=] = s;
fat[s] = ;
while( bg<=ed ) {
int u=qu[bg++];
for( register int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( vis[v] || v==fat[u] ) continue;
qu[++ed] = v;
fat[v] = u;
}
}
}
inline void update( const Point &p, int u ) {
dnt v = p.y + wp[u]*(dep[u]-p.x) + wq[u];
if( dp[u]>v ) dp[u]=v;
}
bool cmp( int a, int b ) {
return dep[a]-lim[a]>dep[b]-lim[b];
}
void vdcp( int s ) {
int c=getc(s);
vis[c] = true;
if( c==s ) {
Point pc = Point(dep[c],dp[c]);
flood(s);
for( int i=; i<=ed; i++ ) {
int u=qu[i];
if( u!=s && dep[u]-lim[u]<=pc.x ) update(pc,u);
}
} else {
vdcp(s);
flood(c);
sort( qu+, qu++ed, cmp );
convex.init();
int cur = c;
for( register int i=; i<=ed; i++ ) {
int u=qu[i];
while( cur!=s && dep[anc[cur]]>=dep[u]-lim[u] ) {
cur=anc[cur];
convex.append( Point(dep[cur],dp[cur]) );
}
if( convex.top>= )
update( convex.query(wp[u]), u );
}
Point cp = Point(dep[c],dp[c]);
for( register int i=ed; i>=; i-- ) {
int u=qu[i];
if( u==c ) continue;
if( dep[u]-lim[u]>dep[c] ) break;
update( cp, u );
}
}
for( int t=head[c]; t; t=next[t] ) {
int v=dest[t];
if( vis[v] ) continue;
vdcp(v);
}
}
int main() {
scanf( "%d%d", &n, &case_type );
for( int i=; i<=n; i++ ) {
int f;
dnt s;
scanf( "%d%lld%lld%lld%lld", &f, &s, wp+i, wq+i, lim+i );
adde( f, i, s );
adde( i, f, s );
}
fill( dp, , n, 0x3f );
dp[] = ;
bfs();
vdcp();
for( int i=; i<=n; i++ )
printf( "%lld\n", dp[i] );
}

bzoj 3672 利用点分治将CDQ分治推广到树型结构上的更多相关文章

  1. COGS 2479. [HZOI 2016]偏序 [CDQ分治套CDQ分治 四维偏序]

    传送门 给定一个有n个元素的序列,元素编号为1~n,每个元素有三个属性a,b,c,求序列中满足i<j且ai<aj且bi<bj且ci<cj的数对(i,j)的个数. 对于100%的 ...

  2. NOI 2007 货币兑换Cash (bzoj 1492) - 斜率优化 - 动态规划 - CDQ分治

    Description 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和 B纪念券(以下 简称B券).每个持有金券的顾客都有一个自己的帐户.金券的数目可以是一个 ...

  3. 【BZOJ】1176: [Balkan2007]Mokia(cdq分治)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1176 在写这题的时候思维非常逗啊........2333................... 最后 ...

  4. BZOJ 2726: [SDOI2012]任务安排( dp + cdq分治 )

    考虑每批任务对后面任务都有贡献, dp(i) = min( dp(j) + F(i) * (T(i) - T(j) + S) ) (i < j <= N)  F, T均为后缀和. 与j有关 ...

  5. BZOJ 2716 Violet 3 天使玩偶 CDQ分治

    题目大意:初始给定平面上的一个点集.提供两种操作: 1.将一个点增加点集 2.查询距离一个点最小的曼哈顿距离 K-D树是啥...不会写... 我仅仅会CDQ分治 对于一个询问,查询的点与这个点的位置关 ...

  6. BZOJ 2716: [Violet 3]天使玩偶( CDQ分治 + 树状数组 )

    先cdq分治, 然后要处理点对答案的贡献, 可以以询问点为中心分成4个区域, 然后去掉绝对值(4种情况讨论), 用BIT维护就行了. --------------------------------- ...

  7. 【BZOJ 3262】 3262: 陌上花开 (CDQ分治)

    3262: 陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A ...

  8. BZOJ 2716 [Violet 3]天使玩偶 (CDQ分治、树状数组)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2716 怎么KD树跑得都那么快啊..我写的CDQ分治被暴虐 做四遍CDQ分治,每次求一个 ...

  9. BZOJ 1935 Tree 园丁的烦恼 CDQ分治/主席树

    CDQ分治版本 我们把询问拆成四个前缀和,也就是二维前缀和的表达式, 我们把所有操作放入一个序列中 操作1代表在x,y出现一个树 操作2代表加上在x,y内部树的个数 操作3代表减去在x,y内部树的个数 ...

随机推荐

  1. Css中实现一个盒子固定宽度,另一个盒子宽度自适应的方法

    Css中实现一个盒子固定宽度,另一个盒子宽度自适应的方法 网上方法很多,个人认为以下两种思想是最为常用的. 一种是让第一个盒子脱离文档流,第二个盒子离左边有一定距离. 第二种方法是使用flex布局,不 ...

  2. CentOS7.3下的一个iptables配置

    centos7.3默认使用的防火墙应该是firewall,而不是iptables.而我们xxmj服务器使用的是iptables防火墙.所以,在配置防火墙之前,我们需要先关闭firewall,安装ipt ...

  3. Sort Colors I & II

    Given an array with n objects colored red, white or blue, sort them so that objects of the same colo ...

  4. 解决 Windows 环境 Git Bash 无法识别 Composer 命令的问题

    思路 模拟 Linux,复制一个 composer 文件到 Git Bash 的 /usr 的子目录,并赋予执行权限. 解决 首先,请确定你的 composer.phar 文件路径.我的是: /d/w ...

  5. Linux Kernel sys_call_table、Kernel Symbols Export Table Generation Principle、Difference Between System Calls Entrance In 32bit、64bit Linux【转】

    转自:http://www.cnblogs.com/LittleHann/p/4127096.html 目录 1. sys_call_table:系统调用表 2. 内核符号导出表:Kernel-Sym ...

  6. idea git revert 究竟做了啥

    git里面实现撤销commit 这个据我目前所知,有至少4个途径可以做到 1.git reset 2.git revert 3.git rm –cached 4.git checkout 这个可以参考 ...

  7. supervisor的安装和配置

    1. 安装 yum install supervisor 2.配置 [unix_http_server] file=/tmp/supervisor.sock ;UNIX socket 文件,super ...

  8. DedeCMS栏目页调用当前栏目名和上级栏目名

    在构建网页的时候,如果不想逐个写栏目列表页的标题,即列表页标题形式为:{field:seotitle/}_{dede:global.cfg_webname/},其中{field:seotitle/}为 ...

  9. DEDECMS去除后门隐患和漏洞以及冗余代码的方法

    链接:http://jingyan.baidu.com/article/4d58d541195bdb9dd4e9c029.html 工具/原料 织梦网站管理系统 sublime编辑器 方法/步骤 第一 ...

  10. Codeforce 295B Greg and Graph(Floyd的深入理解)

    题目链接:http://codeforces.com/problemset/problem/295/B 题目大意:给出n个点的完全有权有向图,每次删去一个点,求删掉该点之前整张图各个点的最短路之和(包 ...