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

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. 怎么修改oracle用户密码

    在以SYSDBA身份登陆时可以修改其他用户的密码,比如: SQL> alter user user01 identified by user10;

  2. 【CTF MISC】文件内容反转方法-2017世安杯CTF writeup详解

    Reverseme 用winhex打开,发现里面的字符反过来可以正常阅读,所以文件被倒置了 Python解题程序如下 with open('reverseMe','rb') as f: with op ...

  3. 如何调整Linux内核启动中的驱动初始化顺序-驱动加载优先级

    Linux内核为不同驱动的加载顺序对应不同的优先级,定义了一些宏: include\linux\init.h #define pure_initcall(fn) __define_initcall(& ...

  4. Team Foundation Server 2010服务器安装

    本安装指南使用Windows Server 2008企业版为基础,安装Windows Server 2008 SP2(必须),在此操作系统环境上进行TFS2010的安装与配置. 三.系统用户设置 1. ...

  5. HDU 6203 2017沈阳网络赛 LCA,DFS+树状数组

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 题意:n+1 个点 n 条边的树(点标号 0 ~ n),有若干个点无法通行,导致 p 组 U V ...

  6. poj1095

    题意:给出n,要求输出第n个二叉树,二叉树编号规则如下图所示: 分析:g[i]表示有i个节点的二叉树,有多少种.f[i][j]表示有i个节点,且左子树有j个节点的树有多少种. sumg[i]表示g数组 ...

  7. 从bind函数看js中的柯里化

    以下是百度百科对柯里化函数的解释:柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.概念太抽象,可能 ...

  8. Python装饰器讲解

    Python装饰器讲解 定义:本质是函数,就是为其他函数添加附加功能.原则:1.不能修改被装饰的函数的源代码 2.不能修改被装饰的函数的调用方式 import time def timmer(func ...

  9. AngularJs(SPA)单页面SEO以及百度统计应用(上)

    只有两种人最具有吸引力,一种是无所不知的人,一种是一无所知的人 问:学生问追一个女孩总是追不上怎么办?回答:女孩不是追来的,是吸引来的,你追的过程是吸引女孩的过程,如果女孩没有看上你,再追都是没有用的 ...

  10. Elasticsearch的相关知识

    Elasticsearch的备份和恢复 http://keenwon.com/1393.html ETL kettle 数据转成json 发送POST请求 http://blog.csdn.net/a ...