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;
}
本文来自博客园,作者:B_F_S,转载请注明原文链接:https://www.cnblogs.com/Na2SO4/p/23252927

浙公网安备 33010602011771号