看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在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. python Flask post 数据 输出

    #!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flask from flask import request from ...

  2. [iOS]深拷贝/浅拷贝区别

    来点鸡汤: // 所谓拷贝 就是在原有的对象的基础上产生一个新的副本对象.有两点原则: //   1. 改变原对象的属性和行为不会影响副本对象 //   2. 改变副本对象的属性和行为不会影响原对象 ...

  3. Nodejs stream模块-翻译

    花了两天时间尝试按照自己的话翻译了一下stream模块,以下内容皆翻译于:https://nodejs.org/api/stream.html. 目录 1  Stream(流)     1.1     ...

  4. iOS问题#解决方案#之关于“application/x-www-form-urlencoded;charset=utf-8” not supported

    http://www.cnblogs.com/ChenYilong   http://www.cnblogs.com/ChenYilong   如果你用的是AFN/ASI,那得修改源代码了,因为AFN ...

  5. rsync更改端口后的同步办法

    rsync有两种常用的认证方式,一种为rsync-daemon方式,另外一种则是ssh. 在一些场合,使用rsync-daemon方式会比较缺乏灵活性,ssh方式则成为首选.但是今天实际操作的时候发现 ...

  6. 在maven 2工程中加入iTextAsian支持(maven添加自定义jar包到本地仓库)

    最近需要在工程中加入JasperReports,其中要用到把报表导出为pdf文件的功能.JasperReports内部使用iText来输出pdf文档,而iText对中文是放在单独的包iTextAsia ...

  7. struts与ognl结合【重要】

    -----------------------------ognl表达式------------------------ OGNL:对象视图导航语言.  ${user.addr.name} 这种写法就 ...

  8. python3之模板pycurl探测web服务质量

    1.pycurl简介 pycURL是libcurl多协议文件传输库的python接口,与urllib模块类似,PycURL可用于从python程序中获取由URL标识的对象,功能很强大,libcurl速 ...

  9. 大数据系列之分布式计算批处理引擎MapReduce实践-排序

    清明刚过,该来学习点新的知识点了. 上次说到关于MapReduce对于文本中词频的统计使用WordCount.如果还有同学不熟悉的可以参考博文大数据系列之分布式计算批处理引擎MapReduce实践. ...

  10. 兼容IE FF 获取鼠标位置

    由于Firefox和IE等浏览器之间对js解释的方式不一样,firefox下面获取鼠标位置不能够直接使用clientX来获取.网上说的一般都是触发mousemove事件才行.我这里有两段代码,思路都一 ...