1. 程式人生 > >【Luogu3398】倉鼠找sugar(樹鏈剖分)

【Luogu3398】倉鼠找sugar(樹鏈剖分)

name -m pac tor int modify 可能 iostream algorithm

【Luogu3398】倉鼠找sugar(樹鏈剖分)

題面

題目描述

小倉鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每個節點的編號為1~n。地下洞穴是一個樹形結構。這一天小倉鼠打算從從他的臥室(a)到餐廳(b),而他的基友同時要從他的臥室(c)到圖書館(d)。他們都會走最短路徑。現在小倉鼠希望知道,有沒有可能在某個地方,可以碰到他的基友?

小倉鼠那麽弱,還要天天被zzq大爺虐,請你快來救救他吧!

輸入輸出格式

輸入格式:
第一行兩個正整數n和q,表示這棵樹節點的個數和詢問的個數。

接下來n-1行,每行兩個正整數u和v,表示節點u到節點v之間有一條邊。

接下來q行,每行四個正整數a、b、c和d,表示節點編號,也就是一次詢問,其意義如上。

輸出格式:
對於每個詢問,如果有公共點,輸出大寫字母“Y”;否則輸出“N”。

輸入輸出樣例

輸入樣例#1:
5 5
2 5
4 2
1 3
1 4
5 1 5 1
2 2 1 4
4 1 3 4
3 1 1 5
3 5 1 4
輸出樣例#1:
Y
N
Y
Y
Y

題解

比較簡單吧。。。
懶得多想了
每次的兩條路徑,一次修改,一次查詢
修改就把第一條路徑上面的點全部搞一下(比如記錄一下當前是第幾組詢問)
然後再檢查一下第二條路徑上是否存在標記即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath> #include<algorithm> #include<set> #include<map> #include<vector> #include<queue> using namespace std; #define MAX 101000 #define lson (now<<1) #define rson (now<<1|1) struct Line { int v,next; }e[MAX<<1]; int h[MAX],cnt=1; inline
void Add(int u,int v) { e[cnt]=(Line){v,h[u]}; h[u]=cnt++; } inline int read() { int x=0,t=1;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=-1,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return x*t; } struct Node { int v; int l; }t[MAX<<2]; int fa[MAX],size[MAX],hson[MAX],dep[MAX],dfn[MAX],tim; int top[MAX],low[MAX],n,L,R,W; void dfs1(int u,int ff) { fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1; for(int i=h[u];i;i=e[i].next) { int v=e[i].v; if(v==ff)continue; dfs1(v,u); size[u]+=size[v]; if(size[v]>size[hson[u]])hson[u]=v; } } void dfs2(int u,int tp) { top[u]=tp;dfn[u]=++tim; if(hson[u])dfs2(hson[u],tp); for(int i=h[u];i;i=e[i].next) { int v=e[i].v; if(v==hson[u]||v==fa[u])continue; dfs2(v,v); } low[u]=tim; } void putlazy(int now,int w) { t[now].v=t[now].l=w; } void pushdown(int now) { if(!t[now].l)return; t[lson].v=t[rson].v=t[now].l; t[lson].l=t[rson].l=t[now].l; t[now].l=0; } void Modify(int now,int l,int r) { if(l>=L&&r<=R){putlazy(now,W);return;} pushdown(now); int mid=(l+r)>>1; if(R>mid)Modify(rson,mid+1,r); if(L<=mid)Modify(lson,l,mid); t[now].v=max(t[lson].v,t[rson].v); } int Query(int now,int l,int r) { if(l>=L&&r<=R){return t[now].v;} pushdown(now); int mid=(l+r)>>1; int ret=0; if(R>mid)ret=max(ret,Query(rson,mid+1,r)); if(L<=mid)ret=max(ret,Query(lson,l,mid)); return ret; } void jump1(int u,int v) { while(top[u]!=top[v]) { if(dep[top[u]]<dep[top[v]])swap(u,v); L=dfn[top[u]],R=dfn[u]; Modify(1,1,n); u=fa[top[u]]; } if(dep[u]<dep[v])swap(u,v); L=dfn[v],R=dfn[u]; Modify(1,1,n); } int jump2(int u,int v) { int ret=0; while(top[u]!=top[v]) { if(dep[top[u]]<dep[top[v]])swap(u,v); L=dfn[top[u]],R=dfn[u]; ret=max(ret,Query(1,1,n)); u=fa[top[u]]; } if(dep[u]<dep[v])swap(u,v); L=dfn[v],R=dfn[u]; ret=max(ret,Query(1,1,n)); return ret; } int main() { n=read();int Q=read(); for(int i=1;i<n;++i) { int u=read(),v=read(); Add(u,v);Add(v,u); } dfs1(1,0);dfs2(1,1); while(Q--) { int u=read(),v=read();W++; jump1(u,v); u=read(),v=read(); jump2(u,v)==W?puts("Y"):puts("N"); } return 0; }

【Luogu3398】倉鼠找sugar(樹鏈剖分)