洛谷 3398 仓鼠找sugar——树链剖分

题目:https://www.luogu.org/problemnew/show/P3398

原来只要把值记录成第几次就行了。

别忘了while(top[a]!=top[b])之后还要走一步。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+5;
int n,q,hd[N],xnt,nxt[N<<1],to[N<<1],tim,top[N],fa[N],siz[N],son[N],dep[N],rnk[N];
int ls[N<<1],rs[N<<1],val[N<<1],laz[N<<1];
int rdn()
{
    int ret=0;char ch=getchar();
    while(ch>'9'||ch<'0')ch=getchar();
    while(ch>='0'&&ch<='9')(ret*=10)+=ch-'0',ch=getchar();
    return ret;
}
void add(int x,int y)
{
    to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;
    to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;
}
void dfs(int cr,int f)
{
    fa[cr]=f;dep[cr]=dep[f]+1;siz[cr]=1;
    for(int i=hd[cr],v;i;i=nxt[i])
        if((v=to[i])!=f)
        {
            dfs(v,cr);siz[cr]+=siz[v];
            if(siz[v]>siz[son[cr]])son[cr]=v;
        }
}
void dfs(int cr)
{
    rnk[cr]=++tim;
    if(son[cr])top[son[cr]]=top[cr],dfs(son[cr]);
    for(int i=hd[cr],v;i;i=nxt[i])
        if((v=to[i])!=fa[cr]&&v!=son[cr])
        {top[v]=v;dfs(v);}
}
void build(int l,int r,int cr)
{
    val[cr]=N;laz[cr]=N;
    if(l==r)return;int mid=l+r>>1;
    ls[cr]=++tim;build(l,mid,ls[cr]);
    rs[cr]=++tim;build(mid+1,r,rs[cr]);
}
void pshd(int cr)
{
    if(laz[cr]==N)return;
    laz[ls[cr]]=laz[rs[cr]]=val[ls[cr]]=val[rs[cr]]=laz[cr];
    laz[cr]=N;
}
void pshp(int cr)
{
    val[cr]=min(val[ls[cr]],val[rs[cr]]);
}
void mdfy(int l,int r,int cr,int L,int R,int w)
{
//    printf("mdfy L=%d R=%d l=%d r=%d val=%d w=%d\n",L,R,l,r,val[cr],w);
    if(l>=L&&r<=R){val[cr]=laz[cr]=w;return;}
    int mid=l+r>>1;pshd(cr);
    if(L<=mid)mdfy(l,mid,ls[cr],L,R,w);
    if(mid<R)mdfy(mid+1,r,rs[cr],L,R,w);
    pshp(cr);
}
void mdfy(int a,int b,int w)
{
    while(top[a]!=top[b])
    {
        if(dep[top[a]]>dep[top[b]])swap(a,b);
        mdfy(1,n,1,rnk[top[b]],rnk[b],w);b=fa[top[b]];
    }
    if(dep[a]>dep[b])swap(a,b);
    mdfy(1,n,1,rnk[a],rnk[b],w);
}
bool query(int l,int r,int cr,int L,int R)
{
//    printf("query L=%d R=%d l=%d r=%d val=%d laz=%d\n",L,R,l,r,val[cr],laz[cr]);
    if(l>=L&&r<=R)return val[cr]==q;
    int mid=l+r>>1;pshd(cr);
    bool ret=0;
    if(L<=mid)ret|=query(l,mid,ls[cr],L,R);
    if(mid<R)ret|=query(mid+1,r,rs[cr],L,R);
    return ret;
}
bool query(int a,int b)
{
    bool ret=0;
    while(top[a]!=top[b])
    {
        if(dep[top[a]]>dep[top[b]])swap(a,b);
        ret|=query(1,n,1,rnk[top[b]],rnk[b]);b=fa[top[b]];
    }
    if(dep[a]>dep[b])swap(a,b);
    ret|=query(1,n,1,rnk[a],rnk[b]);
    return ret;
}
int main()
{
    n=rdn();q=rdn();int a,b,c,d;
    for(int i=1;i<n;i++)
    {
        a=rdn();b=rdn();add(a,b);
    }
    dfs(1,0);top[1]=1;dfs(1);
    tim=1;val[0]=N;build(1,n,1);
    while(q--)
    {
//        printf("q=%d\n",q);
        a=rdn();b=rdn();c=rdn();d=rdn();
        mdfy(a,b,q);
        if(query(c,d))puts("Y");else puts("N");
    }
    return 0;
}

 

posted on 2018-08-04 19:14  Narh  阅读(167)  评论(0编辑  收藏  举报

导航