[HNOI2016]网络
problem
solution
另辟蹊径,不把交互请求赋在新增路径上,反而把交互请求赋在树上除去该请求路径覆盖点的其它点上
显然,路径问题树剖是非常可以的、
那么一个点上的信息就表示所有不经过该点的交互请求,用堆存储下来
但是又有交互请求删除问题,就在点上再来一个堆存储已经删除的请求
查询就相当于单点查询,两个大根堆,如果堆头相同,就删去,直到堆头不同
code
#include <queue>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 200005
pair < int, int > path[maxn];
int n, m, cnt;
vector < int > G[maxn];
int dfn[maxn], dep[maxn], Top[maxn], siz[maxn], son[maxn], f[maxn];struct node {int u, v, w;node(){}node( int U, int V, int W ) {u = U, v = V, w = W;}
}opt[maxn];class New_Queue {private :priority_queue < int > Delete, Vis;public :int find() {while( ! Delete.empty() && ! Vis.empty() ) {if( Delete.top() == Vis.top() )Delete.pop(), Vis.pop();elsebreak;}return Vis.empty() ? -1 : Vis.top();}void insert( int x ) {Vis.push( x );}void erase( int x ) {Delete.push( x );}
};class SegMentTree {private :New_Queue t[maxn << 2];public :void modify( int num, int l, int r, int L, int R, int w, int opt ) {if( r < L || R < l ) return;if( L <= l && r <= R ) {opt ? t[num].insert( w ) : t[num].erase( w );return;}int mid = ( l + r ) >> 1;modify( num << 1, l, mid, L, R, w, opt );modify( num << 1 | 1, mid + 1, r, L, R, w, opt );}int query( int num, int l, int r, int pos ) {if( l == r ) return t[num].find();int mid = ( l + r ) >> 1;if( pos <= mid )return max( t[num].find(), query( num << 1, l, mid, pos ) );elsereturn max( t[num].find(), query( num << 1 | 1, mid + 1, r, pos ) );}
}MS;void dfs1( int u, int fa ) {f[u] = fa, dep[u] = dep[fa] + 1, siz[u] = 1;for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];if( v == fa ) continue;else dfs1( v, u );siz[u] += siz[v];if( ! son[u] || siz[v] > siz[son[u]] )son[u] = v;}
}void dfs2( int u, int t ) {dfn[u] = ++ cnt, Top[u] = t;if( ! son[u] ) return;else dfs2( son[u], t );for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];if( v == f[u] || v == son[u] ) continue;else dfs2( v, v );}
}void modify( int u, int v, int w, int opt ) {cnt = 0;while( Top[u] ^ Top[v] ) {if( dep[Top[u]] < dep[Top[v]] ) swap( u, v );path[++ cnt] = make_pair( dfn[Top[u]], dfn[u] );u = f[Top[u]];}if( dep[u] < dep[v] ) swap( u, v );path[++ cnt] = make_pair( dfn[v], dfn[u] );sort( path + 1, path + cnt + 1 );for( int i = 1, k = 0;i <= cnt;k = path[i ++].second )if( k + 1 != path[i].first )MS.modify( 1, 1, n, k + 1, path[i].first - 1, w, opt );if( path[cnt].second ^ n )MS.modify( 1, 1, n, path[cnt].second + 1, n, w, opt );
}int main() {scanf( "%d %d", &n, &m );for( int i = 1, u, v;i < n;i ++ ) {scanf( "%d %d", &u, &v );G[u].push_back( v );G[v].push_back( u );}dfs1( 1, 0 ), dfs2( 1, 1 );for( int i = 1, type, a, b, v;i <= m;i ++ ) {scanf( "%d %d", &type, &a );switch( type ) {case 0 : {scanf( "%d %d", &b, &v );opt[i] = node( a, b, v );modify( a, b, v, 1 );break;}case 1 : {modify( opt[a].u, opt[a].v, opt[a].w, 0 );break;}case 2 : {printf( "%d\n", MS.query( 1, 1, n, dfn[a] ) );break;}}}return 0;
}