当前位置: 首页 > news >正文

牛客练习赛42 E.热爆了

这可能是全场最长的一份代码

问的其实是对于关键点的斯坦纳树大小

考虑补集转化,不合法的点就是它的子树中没有关键点的点和斯坦纳树根的祖先

树根不难求,关键点中dfs序最大最小点的LCA就是了

问题在前者

假如我们把子树中的点拿出来排序,这个点不合法的条件就是存在ax,ax+1满足ax<=l-1且r+1<=ax+1,有个很妙的性质就是这个合法的x只有1个

考虑启发式合并把这个顺序搞出来,可以证明点数是nlogn级别的,因为每次合并均摊加入logn个点,合并n次。数列相邻的两项成为一个点,插入要用到一棵splay来维护一下。。。

把这些点放到二维平面二维数点即可。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int _=1e2;
const int maxn=1e5+_;
const int maxQ=5e5+_;
const int mbit=30;
const int fbin=(1<<17)+_;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
void write(int x)
{
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
int n,Q;
struct node
{
    int x,y,next;
}a[2*maxn];int len,last[maxn],d[maxn];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}

//--------------------------------------------def-------------------------------------------------------

namespace TREE
{
    namespace Segtree
    {
        struct segtree{int mx,mn;segtree(){mn=(1<<30);}}tr[2*fbin];
        void update(int now)
        {
            int lc=(now<<1),rc=(now<<1|1);
            tr[now].mx=max(tr[lc].mx,tr[rc].mx);
            tr[now].mn=min(tr[lc].mn,tr[rc].mn);
        }
        void pushdown(int now)
        {
            int lc=(now<<1),rc=(now<<1|1);
            tr[lc].mx=max(tr[now].mx,tr[lc].mx);
            tr[rc].mn=min(tr[now].mn,tr[rc].mn);
        }
        void change(int now,int ql,int qr,int p,int k)
        {
            if(ql==qr)
            {
                tr[now].mx=max(tr[now].mx,k);
                tr[now].mn=min(tr[now].mn,k);
                return ;
            }
            int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2;
            pushdown(now);
            if(p<=mid)change(lc,ql,mid,p,k);
            else change(rc,mid+1,qr,p,k);
            update(now);
        }
        int getmax(int now,int ql,int qr,int l,int r)
        {
            if(ql==l&&qr==r)return tr[now].mx;
            int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2;
            pushdown(now);
                 if(r<=mid)  return getmax(lc,ql,mid,l,r);
            else if(mid+1<=l)return getmax(rc,mid+1,qr,l,r);
            else return max(getmax(lc,ql,mid,l,mid),getmax(rc,mid+1,qr,mid+1,r));
        }
        int getmin(int now,int ql,int qr,int l,int r)
        {
            if(ql==l&&qr==r)return tr[now].mn;
            int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2;
            pushdown(now);
                 if(r<=mid)  return getmin(lc,ql,mid,l,r);
            else if(mid+1<=l)return getmin(rc,mid+1,qr,l,r);
            else return min(getmin(lc,ql,mid,l,mid),getmin(rc,mid+1,qr,mid+1,r));
        }
    }
    //~~~~~~~~~~~~~~getnum~~~~~~~~~~~~~~~~~
    
    int z,pos[maxn];
    int dep[maxn],fa[mbit][maxn];
    void dfs(int x,int fr)
    {
        pos[++z]=x;
        Segtree::change(1,1,n,d[x],z);
        for(int i=1;(1<<i)<=dep[x];i++)fa[i][x]=fa[i-1][fa[i-1][x]];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fa[0][x])
            {
                fa[0][y]=x;
                dep[y]=dep[x]+1;
                dfs(y,x);
            }
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=25;i>=0;i--)
            if(dep[x]-dep[y]>=(1<<i))x=fa[i][x];
        if(x==y)return x;
        for(int i=25;i>=0;i--)
            if(dep[x]>=(1<<i)&&fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];
        return fa[0][x];
    }
    int getnum(int l,int r)
    {
        return dep[LCA(pos[Segtree::getmax(1,1,n,l,r)],pos[Segtree::getmin(1,1,n,l,r)])];
    }
    //~~~~~~~~~~~~~~~make~~~~~~~~~~~~~~~~~
    
    int ls[maxn],id[maxn];
    bool cmp(int x,int y){return d[x]<d[y];}
    int getl(int l){return lower_bound(ls+1,ls+n+1,l)-ls;}
    int getr(int r){return upper_bound(ls+1,ls+n+1,r)-ls-1;}
    void LSH()
    {
        for(int i=1;i<=n;i++)ls[i]=d[i],id[i]=i;
        sort(ls+1,ls+n+1);
        sort(id+1,id+n+1,cmp);
        for(int i=1;i<=n;i++)d[id[i]]=i;
    }
    //~~~~~~~~~~~~~~~~LSH~~~~~~~~~~~~~~~~
    
    void main(){LSH();dfs(1,0);}
}

//--------------------------------------------------------------------------------------------

namespace COUNT
{
    namespace Chair
    {
        struct chairmantree
        {
            int lc,rc,c;
        }tr[100*maxn];int trlen,rt[maxn];
        int insert(int x,int ql,int qr,int p,int c)
        {
            if(x==0)x=++trlen;
            tr[x].c+=c;
            if(ql==qr)return x;
            int mid=(ql+qr)/2;
            if(p<=mid)tr[x].lc=insert(tr[x].lc,ql,mid,p,c);
            else tr[x].rc=insert(tr[x].rc,mid+1,qr,p,c);
            return x;
        }
        int merge(int x,int y)
        {
            if(x==0||y==0)return x+y;
            tr[x].c+=tr[y].c;
            tr[x].lc=merge(tr[x].lc,tr[y].lc);
            tr[x].rc=merge(tr[x].rc,tr[y].rc);
            return x;
        }
        int getsum(int now,int ql,int qr,int l,int r)
        {
            if(ql==l&&qr==r){return tr[now].c;}
            int lc=tr[now].lc,rc=tr[now].rc,mid=(ql+qr)/2;
                  if(r<=mid)  return getsum(lc,ql,mid,l,r);
            else if(mid+1<=l)return getsum(rc,mid+1,qr,l,r);
            else return getsum(lc,ql,mid,l,mid)+getsum(rc,mid+1,qr,mid+1,r);
        }
        
        void newid(int &x,int &y){x++,y=n+1-y+1;}
        void paint(int x,int y,int c)
        {
            newid(x,y);
            rt[x]=insert(rt[x],1,n+1,y,c);
        }
        int getnum(int x,int y)
        {
            newid(x,y);
            return getsum(rt[x],1,n+1,1,y);
        }
        void pre()
        {
            for(int i=1;i<=n+1;i++)
                rt[i]=merge(rt[i],rt[i-1]);
        }
    }
    namespace Splay
    {
        struct splay
        {
            int f,son[2];
            int q,x,c,lazy;
        }tr[30*maxn];int trlen,rt[maxn],tot[maxn],id[2*30*maxn],idtp;
        void init(){for(int i=1;i<30*maxn;i++)id[i]=i;idtp=30*maxn;}
        void tap(int w){tr[rt[w]].c++,tr[rt[w]].lazy++;}
        void rotate(int x,int w)
        {
            int f=tr[x].f,ff=tr[f].f;
            int R,r;
            
            R=f,r=tr[x].son[w];
            tr[R].son[1-w]=r;
            if(r!=0)tr[r].f=R;
            
            R=ff,r=x;
            if(tr[ff].son[0]==f)tr[R].son[0]=r;
            else tr[R].son[1]=r;
            tr[r].f=R;
            
            R=x,r=f;
            tr[R].son[w]=r;
            tr[r].f=R;
        }
        void pushdown(int now)
        {
            int lc=tr[now].son[0],rc=tr[now].son[1];
            tr[lc].c+=tr[now].lazy,tr[lc].lazy+=tr[now].lazy;
            tr[rc].c+=tr[now].lazy,tr[rc].lazy+=tr[now].lazy;
            tr[now].lazy=0;
        }
        int tt,tmp[maxn];
        void splay(int x,int F,int w)
        {
            int i=x; tt=0;
            while(i!=F)
                tmp[++tt]=i,i=tr[i].f;
            while(tt>0)
            { 
                if(tr[tmp[tt]].lazy!=0)pushdown(tmp[tt]);
                tt--;
            }
             
            while(tr[x].f!=F)
            {
                int f=tr[x].f,ff=tr[f].f;
                if(ff==F)
                {
                    if(tr[f].son[0]==x)rotate(x,1);
                    else rotate(x,0);
                }
                else
                {
                         if(tr[ff].son[0]==f&&tr[f].son[0]==x)rotate(f,1),rotate(x,1);
                    else if(tr[ff].son[1]==f&&tr[f].son[1]==x)rotate(f,0),rotate(x,0);
                    else if(tr[ff].son[0]==f&&tr[f].son[1]==x)rotate(x,0),rotate(x,1);
                    else if(tr[ff].son[1]==f&&tr[f].son[0]==x)rotate(x,1),rotate(x,0);
                }
            }
            if(F==0)rt[w]=x;
        }
        //~~~~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~~~
        
        int findip(int w,int d)
        {
            int x=rt[w];
            while(1)
            {
                pushdown(x);
                int lc=tr[x].son[0],rc=tr[x].son[1];
                if(d<tr[x].x)
                {
                    if(lc==0)return x;
                    x=lc;
                }
                else
                {
                    if(rc==0)return x;
                    x=rc;
                }
            }
        }
        int findqq(int x,int w)
        {
            splay(x,0,w);
            x=tr[x].son[0];
            while(tr[x].son[1]!=0)x=tr[x].son[1];
            return x;
        }
        int findhj(int x,int w)
        {
            splay(x,0,w);
            x=tr[x].son[1];
            while(tr[x].son[0]!=0)x=tr[x].son[0];
            return x;
        }
        //~~~~~~~~~~~~~~~~~~~find~~~~~~~~~~~~~~~~~~~~~~
        
        void add(int x)
        {
            trlen++; if(trlen==2*30*maxn)trlen=1;
            tr[id[trlen]].x=x;
            tr[id[trlen]].c=0,tr[id[trlen]].lazy=0; 
        }
        void insert(int w,int d)
        {
            tot[w]++;add(d);
            if(rt[w]==0)rt[w]=id[trlen];
            else if(tot[w]==2)
            {
                tr[rt[w]].son[1]=id[trlen];
                tr[id[trlen]].f=rt[w];
                tr[id[trlen]].q=0;
            }
            else
            {
                int p=findip(w,d);
                 if(d<tr[p].x)tr[p].son[0]=id[trlen];
                else tr[p].son[1]=id[trlen];
                tr[id[trlen]].f=p;
                
                tr[id[trlen]].q=tr[findqq(id[trlen],w)].x;
                int h=findhj(id[trlen],w);splay(h,0,w);
                if(tr[h].c!=0)Chair::paint(tr[h].q,tr[h].x,tr[h].c),tr[h].c=0;
                tr[h].q=tr[id[trlen]].x;
            }
        }
        //~~~~~~~~~~~~~~~~~base~~~~~~~~~~~~~~~~~~~~~~~~
        
        void dfs(int w,int x)
        {
            if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c);
            if(tr[x].x!=0&&tr[x].x!=n+1)
            {
                insert(w,tr[x].x);
                id[idtp++]=x;
                if(idtp==2*30*maxn)idtp=1;
            }
            pushdown(x);
            if(tr[x].son[0]!=0)dfs(w,tr[x].son[0]);
            if(tr[x].son[1]!=0)dfs(w,tr[x].son[1]);
        }
        void merge(int x,int y) 
        {
            if(tot[x]<tot[y])swap(rt[x],rt[y]),swap(tot[x],tot[y]);
            dfs(x,rt[y]);
        }
        void dfs2(int x)
        {
            if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c);
            pushdown(x);
            if(tr[x].son[0]!=0)dfs2(tr[x].son[0]);
            if(tr[x].son[1]!=0)dfs2(tr[x].son[1]);
        }
        void divi(){dfs2(rt[1]);}
    }
    
    void dfs(int x,int fr)
    {
        for(int k=last[x];k;k=a[k].next)
            if(a[k].y!=fr)dfs(a[k].y,x);
        Splay::insert(x,0);
        Splay::insert(x,n+1);
        Splay::insert(x,d[x]);
        for(int k=last[x];k;k=a[k].next)
            if(a[k].y!=fr)Splay::merge(x,a[k].y);
        Splay::tap(x);
    }
    void main()
    {
        Splay::init();dfs(1,0);
        Splay::divi();
        Chair::pre();
    }
}

//--------------------------------------------------------------------------------------------

namespace QUERY
{
    void main()
    {
        int l,r;
        while(Q--)
        {
            l=read(),r=read();
            l=TREE::getl(l);
            r=TREE::getr(r);
            if(l>r)puts("0");
            else write(n- (TREE::getnum(l,r)) - (COUNT::Chair::getnum(l-1,r+1)) ),putchar('\n');
        }
    }
}

//--------------------------------------------------------------------------------------------


int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int x,y;
    n=read(),Q=read();
    for(int i=1;i<=n;i++)d[i]=read();
    for(int i=1;i<n;i++)
    {
        x=read(),y=read();
        ins(x,y),ins(y,x);
    }
    TREE::main();
    COUNT::main();
    QUERY::main();
    
    return 0;
}

 

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int _=1e2;
const int maxn=1e5+_;
const int maxQ=5e5+_;
const int mbit=30;
const int fbin=(1<<17)+_;
int read()
{
    int x=0,f=1; char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return x*f;
}
void write(int x)
{
    if(x>=10)write(x/10);
    putchar(x%10+'0');
}
int n,Q;
struct node
{
    int x,y,next;
}a[2*maxn];int len,last[maxn],d[maxn];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}

//--------------------------------------------def-------------------------------------------------------

namespace TREE
{
    namespace Segtree
    {
        struct segtree{int mx,mn;segtree(){mn=(1<<30);}}tr[2*fbin];
        void update(int now)
        {
            int lc=(now<<1),rc=(now<<1|1);
            tr[now].mx=max(tr[lc].mx,tr[rc].mx);
            tr[now].mn=min(tr[lc].mn,tr[rc].mn);
        }
        void pushdown(int now)
        {
            int lc=(now<<1),rc=(now<<1|1);
            tr[lc].mx=max(tr[now].mx,tr[lc].mx);
            tr[rc].mn=min(tr[now].mn,tr[rc].mn);
        }
        void change(int now,int ql,int qr,int p,int k)
        {
            if(ql==qr)
            {
                tr[now].mx=max(tr[now].mx,k);
                tr[now].mn=min(tr[now].mn,k);
                return ;
            }
            int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2;
            pushdown(now);
            if(p<=mid)change(lc,ql,mid,p,k);
            else change(rc,mid+1,qr,p,k);
            update(now);
        }
        int getmax(int now,int ql,int qr,int l,int r)
        {
            if(ql==l&&qr==r)return tr[now].mx;
            int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2;
            pushdown(now);
                 if(r<=mid)  return getmax(lc,ql,mid,l,r);
            else if(mid+1<=l)return getmax(rc,mid+1,qr,l,r);
            else return max(getmax(lc,ql,mid,l,mid),getmax(rc,mid+1,qr,mid+1,r));
        }
        int getmin(int now,int ql,int qr,int l,int r)
        {
            if(ql==l&&qr==r)return tr[now].mn;
            int lc=(now<<1),rc=(now<<1|1),mid=(ql+qr)/2;
            pushdown(now);
                 if(r<=mid)  return getmin(lc,ql,mid,l,r);
            else if(mid+1<=l)return getmin(rc,mid+1,qr,l,r);
            else return min(getmin(lc,ql,mid,l,mid),getmin(rc,mid+1,qr,mid+1,r));
        }
    }
    //~~~~~~~~~~~~~~getnum~~~~~~~~~~~~~~~~~
    
    int z,pos[maxn];
    int dep[maxn],fa[mbit][maxn];
    void dfs(int x,int fr)
    {
        pos[++z]=x;
        Segtree::change(1,1,n,d[x],z);
        for(int i=1;(1<<i)<=dep[x];i++)fa[i][x]=fa[i-1][fa[i-1][x]];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(y!=fa[0][x])
            {
                fa[0][y]=x;
                dep[y]=dep[x]+1;
                dfs(y,x);
            }
        }
    }
    int LCA(int x,int y)
    {
        if(dep[x]<dep[y])swap(x,y);
        for(int i=25;i>=0;i--)
            if(dep[x]-dep[y]>=(1<<i))x=fa[i][x];
        if(x==y)return x;
        for(int i=25;i>=0;i--)
            if(dep[x]>=(1<<i)&&fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];
        return fa[0][x];
    }
    int getnum(int l,int r)
    {
        return dep[LCA(pos[Segtree::getmax(1,1,n,l,r)],pos[Segtree::getmin(1,1,n,l,r)])];
    }
    //~~~~~~~~~~~~~~~make~~~~~~~~~~~~~~~~~
    
    int ls[maxn],id[maxn];
    bool cmp(int x,int y){return d[x]<d[y];}
    int getl(int l){return lower_bound(ls+1,ls+n+1,l)-ls;}
    int getr(int r){return upper_bound(ls+1,ls+n+1,r)-ls-1;}
    void LSH()
    {
        for(int i=1;i<=n;i++)ls[i]=d[i],id[i]=i;
        sort(ls+1,ls+n+1);
        sort(id+1,id+n+1,cmp);
        for(int i=1;i<=n;i++)d[id[i]]=i;
    }
    //~~~~~~~~~~~~~~~~LSH~~~~~~~~~~~~~~~~
    
    void main(){LSH();dfs(1,0);}
}

//--------------------------------------------------------------------------------------------

namespace COUNT
{
    namespace Chair
    {
        struct chairmantree
        {
            int lc,rc,c;
        }tr[100*maxn];int trlen,rt[maxn];
        int insert(int x,int ql,int qr,int p,int c)
        {
            if(x==0)x=++trlen;
            tr[x].c+=c;
            if(ql==qr)return x;
            int mid=(ql+qr)/2;
            if(p<=mid)tr[x].lc=insert(tr[x].lc,ql,mid,p,c);
            else tr[x].rc=insert(tr[x].rc,mid+1,qr,p,c);
            return x;
        }
        int merge(int x,int y)
        {
            if(x==0||y==0)return x+y;
            tr[x].c+=tr[y].c;
            tr[x].lc=merge(tr[x].lc,tr[y].lc);
            tr[x].rc=merge(tr[x].rc,tr[y].rc);
            return x;
        }
        int getsum(int now,int ql,int qr,int l,int r)
        {
            if(ql==l&&qr==r){return tr[now].c;}
            int lc=tr[now].lc,rc=tr[now].rc,mid=(ql+qr)/2;
                  if(r<=mid)  return getsum(lc,ql,mid,l,r);
            else if(mid+1<=l)return getsum(rc,mid+1,qr,l,r);
            else return getsum(lc,ql,mid,l,mid)+getsum(rc,mid+1,qr,mid+1,r);
        }
        
        void newid(int &x,int &y){x++,y=n+1-y+1;}
        void paint(int x,int y,int c)
        {
            newid(x,y);
            rt[x]=insert(rt[x],1,n+1,y,c);
        }
        int getnum(int x,int y)
        {
            newid(x,y);
            return getsum(rt[x],1,n+1,1,y);
        }
        void pre()
        {
            for(int i=1;i<=n+1;i++)
                rt[i]=merge(rt[i],rt[i-1]);
        }
    }
    namespace Splay
    {
        struct splay
        {
            int f,son[2];
            int q,x,c,lazy;
        }tr[30*maxn];int trlen,rt[maxn],tot[maxn],id[2*30*maxn],idtp;
        void init(){for(int i=1;i<30*maxn;i++)id[i]=i;idtp=30*maxn;}
        void tap(int w){tr[rt[w]].c++,tr[rt[w]].lazy++;}
        void rotate(int x,int w)
        {
            int f=tr[x].f,ff=tr[f].f;
            int R,r;
            
            R=f,r=tr[x].son[w];
            tr[R].son[1-w]=r;
            if(r!=0)tr[r].f=R;
            
            R=ff,r=x;
            if(tr[ff].son[0]==f)tr[R].son[0]=r;
            else tr[R].son[1]=r;
            tr[r].f=R;
            
            R=x,r=f;
            tr[R].son[w]=r;
            tr[r].f=R;
        }
        void pushdown(int now)
        {
            int lc=tr[now].son[0],rc=tr[now].son[1];
            tr[lc].c+=tr[now].lazy,tr[lc].lazy+=tr[now].lazy;
            tr[rc].c+=tr[now].lazy,tr[rc].lazy+=tr[now].lazy;
            tr[now].lazy=0;
        }
        int tt,tmp[maxn];
        void splay(int x,int F,int w)
        {
            int i=x; tt=0;
            while(i!=F)
                tmp[++tt]=i,i=tr[i].f;
            while(tt>0)
            { 
                if(tr[tmp[tt]].lazy!=0)pushdown(tmp[tt]);
                tt--;
            }
             
            while(tr[x].f!=F)
            {
                int f=tr[x].f,ff=tr[f].f;
                if(ff==F)
                {
                    if(tr[f].son[0]==x)rotate(x,1);
                    else rotate(x,0);
                }
                else
                {
                         if(tr[ff].son[0]==f&&tr[f].son[0]==x)rotate(f,1),rotate(x,1);
                    else if(tr[ff].son[1]==f&&tr[f].son[1]==x)rotate(f,0),rotate(x,0);
                    else if(tr[ff].son[0]==f&&tr[f].son[1]==x)rotate(x,0),rotate(x,1);
                    else if(tr[ff].son[1]==f&&tr[f].son[0]==x)rotate(x,1),rotate(x,0);
                }
            }
            if(F==0)rt[w]=x;
        }
        //~~~~~~~~~~~~~~~~~~~~in~~~~~~~~~~~~~~~~~~~~~~
        
        int findip(int w,int d)
        {
            int x=rt[w];
            while(1)
            {
                pushdown(x);
                int lc=tr[x].son[0],rc=tr[x].son[1];
                if(d<tr[x].x)
                {
                    if(lc==0)return x;
                    x=lc;
                }
                else
                {
                    if(rc==0)return x;
                    x=rc;
                }
            }
        }
        int findqq(int x,int w)
        {
            splay(x,0,w);
            x=tr[x].son[0];
            while(tr[x].son[1]!=0)x=tr[x].son[1];
            return x;
        }
        int findhj(int x,int w)
        {
            splay(x,0,w);
            x=tr[x].son[1];
            while(tr[x].son[0]!=0)x=tr[x].son[0];
            return x;
        }
        //~~~~~~~~~~~~~~~~~~~find~~~~~~~~~~~~~~~~~~~~~~
        
        void add(int x)
        {
            trlen++; if(trlen==2*30*maxn)trlen=1;
            tr[id[trlen]].x=x;
            tr[id[trlen]].c=0,tr[id[trlen]].lazy=0; 
        }
        void insert(int w,int d)
        {
            tot[w]++;add(d);
            if(rt[w]==0)rt[w]=id[trlen];
            else if(tot[w]==2)
            {
                tr[rt[w]].son[1]=id[trlen];
                tr[id[trlen]].f=rt[w];
                tr[id[trlen]].q=0;
            }
            else
            {
                int p=findip(w,d);
                 if(d<tr[p].x)tr[p].son[0]=id[trlen];
                else tr[p].son[1]=id[trlen];
                tr[id[trlen]].f=p;
                
                tr[id[trlen]].q=tr[findqq(id[trlen],w)].x;
                int h=findhj(id[trlen],w);splay(h,0,w);
                if(tr[h].c!=0)Chair::paint(tr[h].q,tr[h].x,tr[h].c),tr[h].c=0;
                tr[h].q=tr[id[trlen]].x;
            }
        }
        //~~~~~~~~~~~~~~~~~base~~~~~~~~~~~~~~~~~~~~~~~~
        
        void dfs(int w,int x)
        {
            if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c);
            if(tr[x].x!=0&&tr[x].x!=n+1)
            {
                insert(w,tr[x].x);
                id[idtp++]=x;
                if(idtp==2*30*maxn)idtp=1;
            }
            pushdown(x);
            if(tr[x].son[0]!=0)dfs(w,tr[x].son[0]);
            if(tr[x].son[1]!=0)dfs(w,tr[x].son[1]);
        }
        void merge(int x,int y) 
        {
            if(tot[x]<tot[y])swap(rt[x],rt[y]),swap(tot[x],tot[y]);
            dfs(x,rt[y]);
        }
        void dfs2(int x)
        {
            if(tr[x].c!=0&&tr[x].x!=0)Chair::paint(tr[x].q,tr[x].x,tr[x].c);
            pushdown(x);
            if(tr[x].son[0]!=0)dfs2(tr[x].son[0]);
            if(tr[x].son[1]!=0)dfs2(tr[x].son[1]);
        }
        void divi(){dfs2(rt[1]);}
    }
    
    void dfs(int x,int fr)
    {
        for(int k=last[x];k;k=a[k].next)
            if(a[k].y!=fr)dfs(a[k].y,x);
        Splay::insert(x,0);
        Splay::insert(x,n+1);
        Splay::insert(x,d[x]);
        for(int k=last[x];k;k=a[k].next)
            if(a[k].y!=fr)Splay::merge(x,a[k].y);
        Splay::tap(x);
    }
    void main()
    {
        Splay::init();dfs(1,0);
        Splay::divi();
        Chair::pre();
    }
}

//--------------------------------------------------------------------------------------------

namespace QUERY
{
    void main()
    {
        int l,r;
        while(Q--)
        {
            l=read(),r=read();
            l=TREE::getl(l);
            r=TREE::getr(r);
            if(l>r)puts("0");
            else write(n- (TREE::getnum(l,r)) - (COUNT::Chair::getnum(l-1,r+1)) ),putchar('\n');
        }
    }
}

//--------------------------------------------------------------------------------------------


int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int x,y;
    n=read(),Q=read();
    for(int i=1;i<=n;i++)d[i]=read();
    for(int i=1;i<n;i++)
    {
        x=read(),y=read();
        ins(x,y),ins(y,x);
    }
    TREE::main();
    COUNT::main();
    QUERY::main();
    
    return 0;
}

 

转载于:https://www.cnblogs.com/AKCqhzdy/p/10599411.html

相关文章:

  • Linux内核启动流程分析
  • day16 匿名函数
  • BZOJ 3744 Gty的妹子序列 (分块+树状数组+主席树)
  • 前端——HTML
  • Kali Linux Metasploit Framework
  • 位运算的初了解(二)
  • AtCoder Beginner Contest 120 题解
  • 第三章小结
  • 微信小程序_(组件)icon、text、rich-text、progress四大基础组件
  • 处理机调度算法
  • 上周热点回顾(3.25-3.31)
  • 软工第三次团队作业 - 功能规格说明书
  • [北航软工]技术规格说明书
  • PAT甲级1068 Find More Coins【01背包】
  • 【BZOJ2125】—最短路(圆方树+树链剖分)
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • 2019年如何成为全栈工程师?
  • Android 控件背景颜色处理
  • Apache的基本使用
  • Github访问慢解决办法
  • JavaSE小实践1:Java爬取斗图网站的所有表情包
  • Java编程基础24——递归练习
  • Java多态
  • MySQL-事务管理(基础)
  • nodejs实现webservice问题总结
  • quasar-framework cnodejs社区
  • React的组件模式
  • Redash本地开发环境搭建
  • tweak 支持第三方库
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • 百度小程序遇到的问题
  • 给第三方使用接口的 URL 签名实现
  • 基于axios的vue插件,让http请求更简单
  • 理清楚Vue的结构
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 设计模式走一遍---观察者模式
  • 我看到的前端
  • 译自由幺半群
  • 优秀架构师必须掌握的架构思维
  • 正则表达式小结
  • 自动记录MySQL慢查询快照脚本
  • MyCAT水平分库
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 格斗健身潮牌24KiCK获近千万Pre-A轮融资,用户留存高达9个月 ...
  • %check_box% in rails :coditions={:has_many , :through}
  • (ZT)一个美国文科博士的YardLife
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot电竞专题网站 毕业设计 641314
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (南京观海微电子)——I3C协议介绍
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (一)WLAN定义和基本架构转
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)http协议