求助莫队板子TLE
查看原帖
求助莫队板子TLE
392816
小小蒲公英楼主2024/7/10 14:02
#include<bits/stdc++.h>
#pragma optimize O(2)
using namespace std;
const int maxn = 1e6+10;
int bl[maxn];
struct node
{
	int l,r,id;
	bool operator<( const node & b) const
	{
		return (bl[l] != bl[b.l]) ? bl[l] < bl[b.l] : (bl[l]%2) ? r < b.r : r> b.r;
	}
}ask[maxn];
int ola[maxn],cnttt;
int N,M;
int l[maxn],siz[maxn],fat[maxn],dep[maxn],top[maxn],fa[maxn],fir[maxn],sec[maxn];
int head[maxn],nxt[maxn],to[maxn],cntt;
void add(int u,int v)//链式前向星 
{
	to[++cntt] = v;
	nxt[cntt] = head[u];
	head[u] = cntt;
	return ;
}
//树剖求LCA 
void dfs1(int n,int ffa)
{
	dep[n] = dep[ffa] + 1; fa[n] = ffa;
	for(int j=head[n];j;j=nxt[j])
	{
		int i = to[j];
		if(i == fa[n]) continue;
		dfs1(i,n); siz[n] += siz[i];
		if(siz[i] > siz[fat[n]]) fat[n] = i;
	}
	return ;
}
void dfs2(int n,int anc)
{
	top[n] = anc;
	for(int j=head[n];j;j=nxt[j])
	{
		int i = to[j];
		if(i == fa[n]) continue;
		if(i == fat[n]) dfs2(i,anc);
		else dfs2(i,i);
	}
	return ;
}
int LCA(int u,int v)
{
	while(top[u] != top[v])
	{
		if(dep[u] < dep[v]) swap(u,v);
		u = fa[top[u]];
	}
	return (dep[u] < dep[v]) ? u : v;
}
//Euler序,fir表示第一次出现,sec表示第二次 
void Ola(int n)
{
	ola[++cnttt] = n; fir[n] = cnttt;
	for(int j=head[n];j;j=nxt[j])
	{
		int i = to[j];
		if(i != fa[n]) Ola(i);
	} 
	ola[++cnttt] = n; sec[n] = cnttt;
	return ;
}
bitset<maxn> use;
int tmp,cnt[maxn],ans[maxn],san[maxn];
void add(int n)
{
	use[n] ? tmp -= !--cnt[l[n]] : tmp += !cnt[l[n]]++;
	use[n] = use[n] ^ 1;
	return ;
}
inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9')
        x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int main()
{
	N=read(); M=read(); use.reset();
	for(int i=1;i<=N;i++) san[i] = l[i] =read(),siz[i]=1;
	//离散化 
	sort(san+1,san+1+N);
	int tot = unique(san+1,san+1+N) - san - 1; 
	for(int i=1;i<=N;i++) l[i] = lower_bound(san+1,san+1+tot,l[i]) - san;
	int u,v;
	for(int i=1;i<N;i++)
	{
		u=read(); v=read();
		add(u,v); add(v,u);
	}
	dfs1(1,1); dfs2(1,1); Ola(1);
	int sq = N*2/sqrt(M*2/3);
	for(int i=1;i<=cnttt;i++) bl[i] = ceil(1.0*i/sq);
	for(int i=1;i<=M;i++) ask[i].l=read(),ask[i].r=read(),ask[i].id=i;
	sort(ask+1,ask+1+M);
	int ll=1,rr=0,dl,dr;
	for(int i=1;i<=M;i++)
	{
		int lca = LCA(ask[i].l,ask[i].r);
		if(fir[ask[i].l] > fir[ask[i].r]) swap(ask[i].l,ask[i].r);
		if(lca == ask[i].l || lca == ask[i].r) dl=fir[ask[i].l],dr=fir[ask[i].r];
		else dl=sec[ask[i].l],dr=fir[ask[i].r];
		while(ll < dl) add(ola[ll++]);
		while(ll > dl) add(ola[--ll]);
		while(rr < dr) add(ola[++rr]);
		while(rr > dr) add(ola[rr--]);
		if(lca != ask[i].l && lca != ask[i].r) add(lca);
		ans[ask[i].id] = tmp;
		if(lca != ask[i].l && lca != ask[i].r) add(lca);
	}
	for(int i=1;i<=M;i++) printf("%d\n",ans[i]);
	return 0;
} 
2024/7/10 14:02
加载中...