test

#include<bits/stdc++.h>
using namespace std;
const int N=400005,M=400005;
int hd[N],nxt[M],to[M],tot;
void add_edge(int x,int y){
	to[++tot]=y; nxt[tot]=hd[x]; hd[x]=tot;}
int fa[N],sz[N],dep[N],son[N];
void dfs1(int u,int f,int d){
	fa[u]=f; dep[u]=d; sz[u]=1;
	for(int i=hd[u],v;i;i=nxt[i])
	{
		v=to[i];
		if(v==f) continue;
		dfs1(v,u,d+1);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}
int top[N];
void dfs2(int u,int t){
	top[u]=t;
	if(!son[u]) return;
	dfs2(son[u],t);
	for(int i=hd[u];i;i=nxt[i])
		if(to[i]!=fa[u] && to[i]!=son[u])
			dfs2(to[i],to[i]);
}
int lca(int x,int y){
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	return dep[x]<dep[y]?x:y;
}
bool par[N];
int belong[N];
struct Cmd{
	int l,r,LCA,id,ql,qr;
	bool operator <(const Cmd& p) const{
		if(belong[l]!=belong[p.l]) return belong[l]<belong[p.l];
		return belong[l]&1?r<p.r:r>p.r;
	}
}cmd[N];
int dfn[N],out[N],seq[N],num;
void dfs(int u)
{
	dfn[u]=++num; seq[num]=u;
	for(int i=hd[u],v;i;i=nxt[i])
	{
		v=to[i];
		if(v==fa[u]) continue;
		dfs(v);
	}
	out[u]=++num; seq[num]=u;
}
int B;
int cnt[N],freq[N],blocksum[N];
int block_id[N];//x/B+1
void upd(int x,int a)
{
	// printf("[%d]%+d\n",x,a);
	freq[x]+=a; blocksum[block_id[x]]+=a;
}
int query(int l,int r)
{
	// printf("QUERY [%d,%d]\n",l,r);
	int ans=0,cur=l;
	while(cur<=r && block_id[cur]==block_id[l]){
		ans+=freq[cur];
		++cur;
	}
	while(cur<=r && block_id[cur]<block_id[r]){
		ans+=blocksum[block_id[cur]];
		cur+=B;
	}
	while(cur<=r){
		ans+=freq[cur];
		++cur;
	}
	return ans;
}
int ans[N];
int w[N];
void change(int x)
{
	// printf("CHANGE %d\n",seq[x]);
	int u=seq[x];
	if(par[u]){
		upd(cnt[w[u]],-1);
		--cnt[w[u]];
		upd(cnt[w[u]],1);
	}
	else{
		upd(cnt[w[u]],-1);
		++cnt[w[u]];
		upd(cnt[w[u]],1);
	}
	par[u]^=1;
}
int n,q;
int main()
{
	scanf("%d%d",&n,&q);
	B=int(sqrt(2*n));
	for(int i=1;i<=2*n;i++) belong[i]=i/B;
	for(int i=0;i<=n;i++) block_id[i]=i/B+1;
	for(int i=1;i<=n;i++)
		scanf("%d",&w[i]);
	int u,v,a,b;
	for(int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		add_edge(u,v); add_edge(v,u);
	}
	dfs1(1,0,1);
	dfs2(1,1);
	dfs(1);
	// for(int i=1;i<=num;i++) printf("%d ",seq[i]);
	int L=1,R=0;
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d%d%d",&u,&v,&a,&b);
		if(dfn[u]>dfn[v]) swap(u,v);
		cmd[i]=Cmd{dfn[u]+1,dfn[v],lca(u,v),i,a,b};
	}
	sort(cmd+1,cmd+q+1);
	for(int i=1;i<=q;i++)
	{
		while(L>cmd[i].l) change(--L);
		while(R<cmd[i].r) change(++R);
		while(L<cmd[i].l) change(L++);
		while(R>cmd[i].r) change(R--);
		change(dfn[cmd[i].LCA]);
		ans[cmd[i].id]=query(cmd[i].ql,cmd[i].qr);
		change(dfn[cmd[i].LCA]);
	}
	for(int i=1;i<=q;i++)
		printf("%d\n",ans[i]);
	return 0;
}
posted @ 2026-10-10 15:41  B_F_S  阅读(6)  评论(0)    收藏  举报