看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在O(nlog^3n)的时间复杂度内搞定

这道题用到的一些方法:

  1. 可以将有关的线段提取出来,然后一起处理.

  2. 线段树可以维护两个方向的信息,这样就可以处理树上有序的东西.

 /**************************************************************
Problem: 3999
User: idy002
Language: C++
Result: Accepted
Time:3204 ms
Memory:12144 kb
****************************************************************/ #include <cstdio>
#include <cstring>
#include <algorithm>
#define max(a,b) ((a)>(b)?(a):(b))
#define N 50010
using namespace std; typedef long long dnt;
struct Node {
dnt t, b, a[], tag;
int lf, rg;
Node *ls, *rs;
void pushdown() {
if( tag ) {
ls->t += tag;
ls->b += tag;
ls->tag += tag;
rs->t += tag;
rs->b += tag;
rs->tag += tag;
tag = ;
}
}
void update() {
t = max( ls->t, rs->t );
b = min( ls->b, rs->b );
a[] = max( ls->a[], rs->a[] );
a[] = max( a[], rs->t-ls->b );
a[] = max( ls->a[], rs->a[] );
a[] = max( a[], ls->t-rs->b );
}
void modify( int L, int R, int d ) {
if( L<=lf && rg<=R ) {
t += d;
b += d;
tag += d;
return;
}
pushdown();
int mid=(lf+rg)>>;
if( L<=mid ) ls->modify( L, R, d );
if( R>mid ) rs->modify( L, R, d );
update();
}
}pool[N*], *tail=pool, *root; int n, m;
int head[N], dest[N<<], next[N<<], etot;
int aa[N], bb[N];
int fat[N], dep[N], siz[N], son[N], top[N], vid[N];
int qu[N], bg, ed;
Node *su[N], *sv[N];
int tu, tv; void adde( int u, int v ) {
etot++;
dest[etot] = v;
next[etot] = head[u];
head[u] = etot;
}
Node *build( int lf, int rg ) {
Node *nd = ++tail;
if( lf==rg ) {
nd->b = nd->t = bb[lf];
nd->a[] = nd->a[] = ;
nd->lf=lf, nd->rg=rg;
} else {
int mid=(lf+rg)>>;
nd->ls = build( lf, mid );
nd->rs = build( mid+, rg );
nd->lf=lf, nd->rg=rg;
nd->update();
}
return nd;
}
void fetch( Node *nd, int L, int R, Node *(&stk)[N], int &top ) {
int lf=nd->lf, rg=nd->rg;
if( L<=lf && rg<=R ) {
stk[++top] = nd;
return;
}
int mid=(lf+rg)>>;
nd->pushdown();
if( R>mid ) fetch(nd->rs,L,R,stk,top);
if( L<=mid ) fetch(nd->ls,L,R,stk,top);
}
void build_dcp( int s ) {
// fat dep
fat[s] = ;
dep[s] = ;
qu[bg=ed=] = s;
while( bg<=ed ) {
int u=qu[bg++];
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] ) continue;
fat[v] = u;
dep[v] = dep[u] + ;
qu[++ed] = v;
}
}
// siz son
for( int i=ed; i>=; i-- ) {
int u=qu[i], p=fat[u];
siz[u]++;
if( p ) {
siz[p] += siz[u];
if( siz[u]>siz[son[p]] ) son[p]=u;
}
}
// top vid
top[s] = s;
vid[s] = ;
for( int i=; i<=ed; i++ ) {
int u=qu[i];
int cur=vid[u]+;
if( son[u] ) {
top[son[u]] = top[u];
vid[son[u]] = cur;
cur += siz[son[u]];
}
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] || v==son[u] ) continue;
top[v] = v;
vid[v] = cur;
cur += siz[v];
}
}
// segment
for( int i=; i<=n; i++ )
bb[vid[i]] = aa[i];
root = build( , n );
}
int lca( int u, int v ) {
while( top[u]!=top[v] ) {
if( dep[top[u]]<dep[top[v]] ) swap(u,v);
u = fat[top[u]];
}
return dep[u]<dep[v] ? u : v;
}
dnt query( int u, int v ) {
if( u==v ) return ;
int ca = lca(u,v);
tu = tv = ;
while( top[u]!=top[ca] ) {
fetch(root,vid[top[u]],vid[u],su,tu);
u=fat[top[u]];
}
while( top[v]!=top[ca] ) {
fetch(root,vid[top[v]],vid[v],sv,tv);
v=fat[top[v]];
}
if( u!=ca )
fetch(root,vid[ca],vid[u],su,tu);
else
fetch(root,vid[ca],vid[v],sv,tv);
dnt curt = ;
dnt rt = ;
for( int i=; i<=tv; i++ ) {
rt = max( rt, sv[i]->a[] );
rt = max( rt, curt-sv[i]->b );
curt = max( curt, sv[i]->t );
}
for( int i=tu; i>=; i-- ) {
rt = max( rt, su[i]->a[] );
rt = max( rt, curt-su[i]->b );
curt = max( curt, su[i]->t );
}
return rt;
}
void modify( int u, int v, int d ) {
while( top[u]!=top[v] ) {
if( dep[top[u]]<dep[top[v]] ) swap(u,v);
root->modify(vid[top[u]],vid[u],d);
u=fat[top[u]];
}
if( dep[u]<dep[v] ) swap(u,v);
root->modify(vid[v],vid[u],d);
}
int main() {
scanf( "%d", &n );
for( int i=; i<=n; i++ )
scanf( "%d", aa+i );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
adde( u, v );
adde( v, u );
}
build_dcp();
scanf( "%d", &m );
for( int t=,u,v,d; t<=m; t++ ) {
scanf( "%d%d%d", &u, &v, &d );
printf( "%lld\n", query(u,v) );
modify(u,v,d);
}
}

bzoj 3999 线段树区间提取 有序链剖的更多相关文章

  1. 树链剖分——线段树区间合并bzoj染色

    线段树区间合并就挺麻烦了,再套个树链就更加鬼畜,不过除了代码量大就没什么其他的了.. 一些细节:线段树每个结点用结构体保存,pushup等合并函数改成返回一个结构体,这样好写一些 struct Seg ...

  2. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  3. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  4. 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并

    题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...

  5. [NOI2015] 软件包管理器【树链剖分+线段树区间覆盖】

    Online Judge:Luogu-P2146 Label:树链剖分,线段树区间覆盖 题目大意 \(n\)个软件包(编号0~n-1),他们之间的依赖关系用一棵含\(n-1\)条边的树来描述.一共两种 ...

  6. Bzoj 1798: [Ahoi2009]Seq 维护序列seq(线段树区间操作)

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec Memory Limit: 64 MB Description 老师交给小可可一个维护数列的任务,现在小可 ...

  7. POJ 2823 Sliding Window 线段树区间求和问题

    题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 本题数据量较大,不能用N建树,用n建树. 还有一种做法是单调 ...

  8. CF444C. DZY Loves Colors[线段树 区间]

    C. DZY Loves Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  9. HDU 4509 湫湫系列故事——减肥记II(线段树-区间覆盖 或者 暴力技巧)

    http://acm.hdu.edu.cn/showproblem.php?pid=4509 题目大意: 中文意义,应该能懂. 解题思路: 因为题目给的时间是一天24小时,而且还有分钟.为了解题方便, ...

随机推荐

  1. 《Two Dozen Short Lessons in Haskell》(二十四)代数类型

    这是<Two Dozen Short Lessons in Haskell>这本书的最后一章,第23章没有习题. 这一章里介绍了Haskell如果自定义一种类型,并且用一个双人博弈游戏为例 ...

  2. Vue.js绑定内联样式

    1.对象语法 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...

  3. 图文详解 解决 MVC4 Code First 数据迁移

    在使用Code first生成数据库后 当数据库发生更改时 运行程序就会出现数据已更改的问题  这时可以删除数据库重新生成解决 但是之前的数据就无法保留  为了保留之前的数据库数据  我们需要使用到C ...

  4. Python内置模块与标准库

    Python内置模块就是标准库(模块)吗?或者说Python的自带string模块是内置模块吗? 答案是:string不是内置模块,它是标准库.也就是说Python内置模块和标准库并不是同一种东西. ...

  5. JS脚本病毒调试脚本-Trojan[Downloader]:JS/Nemucod

    1.前言 遇到Trojan[Downloader]:JS/Nemucod需要分析,这款病毒主要为js运行.从网上各种找js调试方法.发现52的帖子还挺沾边的. TrojanDownloader:JS/ ...

  6. USB-HID鼠标、键盘通讯格式【转】

    转自:https://blog.csdn.net/techhome803/article/details/9928873 转自:http://www.amobbs.com/forum.php?mod= ...

  7. kernel——make menuconfig的实现原理【转】

    转自:https://blog.csdn.net/hpr1992/article/details/41048693 .系统移植可以分为配置系统和编译系统两大块,其中通过命令makemenuconfig ...

  8. mysql-8.0.11-winx64 免安装版配置方法

    mysql-8.0.11-winx64.zip  下载地址:https://dev.mysql.com/downloads/file/?id=476233 mysql-8.0.11-winx64.zi ...

  9. 大数据系列之数据仓库Hive命令使用及JDBC连接

    Hive系列博文,持续更新~~~ 大数据系列之数据仓库Hive原理 大数据系列之数据仓库Hive安装 大数据系列之数据仓库Hive中分区Partition如何使用 大数据系列之数据仓库Hive命令使用 ...

  10. MongoDB之pymongo

    PyMongo是什么 PyMongo是驱动程序,使python程序能够使用Mongodb数据库,使用python编写而成. 安装 环境:Ubuntu 14.04+python2.7+MongoDB 2 ...