【Luogu 3398】ハムスターがsugarを探す
問題面
タイトルの説明
ハムスターと彼の友(mei)sugarは地下洞窟に住んでおり,各ノードの番号は1~nである.地下洞窟は木の構造だ.この日、ハムスターは彼の寝室(a)からレストラン(b)まで、彼の親友は同時に彼の寝室(c)から図書館(d)まで行くつもりだった.彼らは最短ルートを歩きます.今ハムスターは、どこかで、彼の親友に会える可能性があるかどうか知りたいと思っています.
ハムスターはそんなに弱くて、また毎日zzqおじいさんに虐げられて、早く助けに来てください!
にゅうしゅつりょくけいしき
入力フォーマット:最初の行の2つの正の整数nとqは、このツリーノードの個数と問い合わせの個数を表す.
次にn−1行、各行の2つの正の整数uおよびvは、ノードuからノードvの間にエッジがあることを示す.
次にq行は、行ごとに4つの正の整数a,b,c,dがノード番号、すなわち1回のクエリを表し、その意味は上述の通りである.
出力フォーマット:各質問に対して、共通点があれば、大文字「Y」を出力します.そうでなければ「N」を出力します.
入出力サンプル
入力サンプル#1:5 5 5 2 5 4 4 2 1 3 1 4 5 1 5 1 5 1 2 1 4 4 1 3 4 1 5 3 4出力サンプル#1:Y Y Y Y Y Y Y Y
問題解
比较的に简単でしょう...毎回の2つのパスを考えるのがおっくうで、1回の修正、1回のクエリーの修正で1つ目のパスの上の点を全部やって(例えば、現在何組目の質問なのかを記録して)、2つ目のパスにマークがあるかどうかをチェックしてください.
タイトルの説明
ハムスターと彼の友(mei)sugarは地下洞窟に住んでおり,各ノードの番号は1~nである.地下洞窟は木の構造だ.この日、ハムスターは彼の寝室(a)からレストラン(b)まで、彼の親友は同時に彼の寝室(c)から図書館(d)まで行くつもりだった.彼らは最短ルートを歩きます.今ハムスターは、どこかで、彼の親友に会える可能性があるかどうか知りたいと思っています.
ハムスターはそんなに弱くて、また毎日zzqおじいさんに虐げられて、早く助けに来てください!
にゅうしゅつりょくけいしき
入力フォーマット:最初の行の2つの正の整数nとqは、このツリーノードの個数と問い合わせの個数を表す.
次にn−1行、各行の2つの正の整数uおよびvは、ノードuからノードvの間にエッジがあることを示す.
次にq行は、行ごとに4つの正の整数a,b,c,dがノード番号、すなわち1回のクエリを表し、その意味は上述の通りである.
出力フォーマット:各質問に対して、共通点があれば、大文字「Y」を出力します.そうでなければ「N」を出力します.
入出力サンプル
入力サンプル#1:5 5 5 2 5 4 4 2 1 3 1 4 5 1 5 1 5 1 2 1 4 4 1 3 4 1 5 3 4出力サンプル#1:Y Y Y Y Y Y Y Y
問題解
比较的に简単でしょう...毎回の2つのパスを考えるのがおっくうで、1回の修正、1回のクエリーの修正で1つ目のパスの上の点を全部やって(例えば、現在何組目の質問なのかを記録して)、2つ目のパスにマークがあるかどうかをチェックしてください.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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]]1,1,n);
u=fa[top[u]];
}
if(dep[u]1,1,n);
}
int jump2(int u,int v)
{
int ret=0;
while(top[u]!=top[v])
{
if(dep[top[u]]1,1,n));
u=fa[top[u]];
}
if(dep[u]1,1,n));
return ret;
}
int main()
{
n=read();int Q=read();
for(int i=1;iint 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;
}