CF487E Tourists
题目很套路,现将利用点双建成圆方树,对于每一个点双的方点用于存周边圆点的min,方点需要用multiset维护圆点儿子的值,当然也需要每个点维护自己的权值。
建树完成后基本就是树剖的板子了,需要注意的是如果找到最后一点一个点事方点的话,需要将方点的父亲进行统计
#include
#define inf 0x7fffffff
#define ll long long
#define re register int
#define void inline void
#define eps 1e-9
#define pb push_back
#define P pair < int , int >
#define mk make_pair
#define fi first
#define se second
#define unordered_map map
#define __int128 long long
#define x0 xx0
#define y0 yy0
using namespace std;
const int mod&#61;1e9&#43;7;
const int N&#61;8e5&#43;5;
int n,m,q,all;
multiset < int > SM[N];
int w[N];
namespace SEG
{#define ls(p) p<<1#define rs(p) p<<1|1int sum[N],a[N];void push(int p){sum[p]&#61;min(sum[ls(p)],sum[rs(p)]);}void bulid(int p,int l,int r){if(l&#61;&#61;r){sum[p]&#61;a[l];return;}int mid&#61;(l&#43;r)>>1;bulid(ls(p),l,mid);bulid(rs(p),mid&#43;1,r);push(p);}void update(int p,int l,int r,int pos,int val){if(l&#61;&#61;r){sum[p]&#61;val;return;}int mid&#61;(l&#43;r)>>1;if(pos<&#61;mid) update(ls(p),l,mid,pos,val);else update(rs(p),mid&#43;1,r,pos,val);push(p);}int ask(int p,int l,int r,int L,int R){if(L<&#61;l&&r<&#61;R) return sum[p];int mid&#61;(l&#43;r)>>1;int ans&#61;1e9;if(L<&#61;mid) ans&#61;min(ans,ask(ls(p),l,mid,L,R));if(mid<R) ans&#61;min(ans,ask(rs(p),mid&#43;1,r,L,R));return ans;}#undef ls#undef rs
}
namespace GP2
{struct node{int ver,next;}e[N];int tot&#61;1,head[N];int d[N],top[N],dfn[N],sz[N],son[N],fa[N];int num;void add(int x,int y){e[&#43;&#43;tot].ver&#61;y;e[tot].next&#61;head[x];head[x]&#61;tot;}void addedge(int x,int y){add(x,y);add(y,x);}void dfs1(int x,int pre){int ma&#61;-1;sz[x]&#61;1;d[x]&#61;d[pre]&#43;1;fa[x]&#61;pre;for(re i&#61;head[x];i;i&#61;e[i].next){int y&#61;e[i].ver;if(y&#61;&#61;pre) continue;dfs1(y,x);sz[x]&#43;&#61;sz[y];if(sz[y]>ma) son[x]&#61;y,ma&#61;sz[y];}}void dfs2(int x,int pre){dfn[x]&#61;&#43;&#43;num;top[x]&#61;pre;if(!son[x]) return;dfs2(son[x],pre);for(re i&#61;head[x];i;i&#61;e[i].next){int y&#61;e[i].ver;if(y&#61;&#61;son[x]||y&#61;&#61;fa[x]) continue;dfs2(y,y);}}void init(){dfs1(1,0);dfs2(1,1);for(re i&#61;1;i<&#61;n;i&#43;&#43;) SEG::a[dfn[i]]&#61;w[i];for(int i&#61;n&#43;1;i<&#61;all;i&#43;&#43;){for(int j&#61;head[i];j;j&#61;e[j].next){int y&#61;e[j].ver;if (y!&#61;fa[i]) SM[i].insert(w[y]);}if(SM[i].empty()) w[i]&#61;1e9;else w[i]&#61;*SM[i].begin();SEG::a[dfn[i]]&#61;w[i];}SEG::bulid(1,1,all);}void add1(int x,int num){int f&#61;fa[x];if(f){SM[f].erase(SM[f].find(w[x]));SM[f].insert(num);w[f]&#61;*SM[f].begin();SEG::update(1,1,all,dfn[f],w[f]);}w[x]&#61;num;SEG::update(1,1,all,dfn[x],num);}int ask(int x,int y){int ans&#61;1e9;while(top[x]!&#61;top[y]){if(d[top[x]]<d[top[y]]) swap(x,y);ans&#61;min(ans,SEG::ask(1,1,all,dfn[top[x]],dfn[x]));x&#61;fa[top[x]];}if(d[x]>d[y]) swap(x,y);ans&#61;min(ans,SEG::ask(1,1,all,dfn[x],dfn[y]));if(x>n) ans&#61;min(ans,w[fa[x]]);return ans;}
}
namespace GP1
{struct node{int ver,next;}e[N];int tot&#61;1,head[N];int dfn[N],low[N];int num,instack[N],top,sum;void add(int x,int y){e[&#43;&#43;tot].ver&#61;y;e[tot].next&#61;head[x];head[x]&#61;tot;}void addedge(int x,int y){add(x,y);add(y,x);}void tarjan(int x,int in_edge){dfn[x]&#61;low[x]&#61;&#43;&#43;sum;instack[&#43;&#43;top]&#61;x;