1 条题解

  • 0
    @ 2026-7-4 23:15:17

    #include <cstdio>
    #include <vector>
    #include <cassert>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int M = 1000005;
    int read()
    {
    	int x=0,f=1;char c;
    	while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
    	while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
    	return x*f;
    }
    void write(int x)
    {
    	if(x>=10) write(x/10);
    	putchar(x%10+'0');
    }
    int n,m,k,a[M],b[M],fa[M][20],dfn[M],dep[M];
    int t,rt,Ind,out[M],ans[M],X[M],Y[M];
    vector<int> g[M],z[M],G[M];
    struct node
    {
    	int x,l,r,f;
    	bool operator < (const node &b) const
    		{return x<b.x;}
    }s[M*10],q[M];
    void dfs(int u)
    {
    	dfn[u]=++k;X[u]=++Ind;
    	dep[u]=dep[fa[u][0]]+1;
    	for(int i=1;i<20;i++)
    		fa[u][i]=fa[fa[u][i-1]][i-1];
    	for(int v:g[u]) if(v^fa[u][0])
    		fa[v][0]=u,dfs(v);
    	out[u]=k;Y[u]=++Ind;
    }
    void ins(int lx,int rx,int ly,int ry)
    {
    	if(lx>rx || ly>ry) return ;
    	s[++t]={lx,ly,ry,1};
    	s[++t]={rx+1,ly,ry,-1};
    }
    void add(int x,int c)
    {
    	for(int i=x;i<=n;i+=i&(-i)) b[i]+=c;
    }
    int ask(int x)
    {
    	int r=0;
    	for(int i=x;i>0;i-=i&(-i)) r+=b[i];
    	return r;
    }
    int find(int u,int v)
    {
    	for(int i=19;i>=0;i--)
    		if(dep[fa[u][i]]>dep[v])
    			u=fa[u][i];
    	return u;
    }
    void zxy(int u,int v)
    {
    	int lu=dfn[u],ru=out[u];
    	int lv=dfn[v],rv=out[v];
    	if(lu<=lv && lv<=ru)//u is a ancestor of v
    	{
    		int x=find(v,u);
    		ins(1,dfn[x]-1,lv,rv);
    		ins(out[x]+1,n,lv,rv);
    	}
    	else if(lv<=lu && lu<=rv)
    	{
    		int x=find(u,v);
    		ins(lu,ru,1,dfn[x]-1);
    		ins(lu,ru,out[x]+1,n);
    	}
    	else ins(lu,ru,lv,rv);
    }
    int cmp(int a,int b)
    {
    	int t1=a>0?X[a]:Y[-a];
    	int t2=b>0?X[b]:Y[-b];
    	return t1<t2;
    }
    int lca(int u,int v)
    {
    	if(dep[u]<dep[v]) swap(u,v);
    	for(int i=19;i>=0;i--)
    		if(dep[fa[u][i]]>=dep[v])
    			u=fa[u][i];
    	if(u==v) return u;
    	for(int i=19;i>=0;i--)
    		if(fa[u][i]^fa[v][i])
    			u=fa[u][i],v=fa[v][i];
    	return fa[u][0];
    }
    void get(int u,int fa,int d)
    {
    	if(b[u]==b[rt])
    	{
    		if(a[u]==1) d++;
    		if(a[u]==2)
    		{
    			d--;
    			if(d==0) zxy(rt,u);
    			if(d<=0) return ;
    		}
    	}
    	for(int v:G[u]) if(v^fa)
    		get(v,u,d);
    }
    signed main()
    {
    	//freopen("keys.in","r",stdin);
    	//freopen("keys.out","w",stdout);
    	n=read();m=read();
    	for(int i=1;i<=n;i++)
    		a[i]=read(),b[i]=read();
    	for(int i=1;i<n;i++)
    	{
    		int u=read(),v=read();
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	dfs(1);
    	for(int i=1;i<=n;i++)
    		z[b[i]].push_back(i);
    	for(int i=1;i<=n;i++) if(!z[i].empty())
    	{
    		static int A[M]={},vis[M]={},s[M]={};
    		int k=0,k2=0,tp=0;
    		for(int x:z[i]) A[++k]=x,vis[x]=1;
    		sort(A+1,A+1+k,cmp);k2=k;
    		for(int i=1;i<k2;i++)
    		{
    			int x=lca(A[i],A[i+1]);
    			if(!vis[x]) vis[x]=1,A[++k]=x;
    		}
    		if(!vis[1]) A[++k]=1,vis[1]=1;k2=k;
    		for(int i=1;i<=k2;i++) A[++k]=-A[i];
    		sort(A+1,A+1+k,cmp);
    		for(int i=1;i<=k;i++)
    		{
    			if(A[i]>0) s[++tp]=A[i];
    			else
    			{
    				int t=s[tp--];
    				if(t==1) break;
    				G[s[tp]].push_back(t);
    				G[t].push_back(s[tp]);
    			}
    		}
    		for(int x:z[i]) if(a[x]==1)
    			rt=x,get(x,0,0);
    		for(int i=1;i<=k;i++) if(A[i]>0)
    			vis[A[i]]=0,G[A[i]].clear();
    	}
    	for(int i=1;i<=m;i++)
    	{
    		int u=read(),v=read();
    		q[i]=node{dfn[u],dfn[v],0,i};
    	}
    	sort(q+1,q+1+m);
    	sort(s+1,s+1+t);
    	for(int i=1;i<=n;i++) b[i]=0;
    	for(int i=1,j=1;i<=m;i++)
    	{
    		while(j<=t && s[j].x<=q[i].x)
    		{
    			add(s[j].l,s[j].f);
    			add(s[j].r+1,-s[j].f);
    			j++;
    		}
    		ans[q[i].f]=ask(q[i].l);
    	}
    	for(int i=1;i<=m;i++)
    		write(ans[i]),puts("");
    }
    
    
    • 1

    信息

    ID
    7245
    时间
    2000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者