树上莫队RE求助
查看原帖
树上莫队RE求助
171487
cmll02楼主2021/4/26 15:08

离散化用了gp_hash_table也REkk

// Problem: SP10707 COT2 - Count on a tree II
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/SP10707
// Memory Limit: 1.46 MB
// Time Limit: 1210 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <bits/extc++.h>
using namespace __gnu_pbds;
inline int read()
{
	int num=0,f=1;char c=getchar();
	while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
	while(c>47&&c<58)num=num*10+(c^48),c=getchar();
	return num*f;
}
#define edge e
#define p nxt
inline int min(int a,int b){return a>b?b:a;}
inline int max(int a,int b){return a<b?b:a;}
#define log(x) Log[x]
struct Edge
{
	int v, p;
}edge[1000086];
int Log[500086], h[500086], cnt = 1;
inline void iniLog(int n)
{
	for (int i = 1; i <= n; i++)Log[i] = Log[i - 1] + (!((1 << Log[i - 1]) ^ i));
}
void addedge(int u, int v)
{
	edge[cnt] = { v, h[u] };
	h[u] = cnt++;
}
int pre[500086][20], depth[500086];
void dfs(int, int);
int LCA(int, int);
int L[200005],R[200005],cc;
int a[1000005],c[1000005];
gp_hash_table<int,int> b;
void dfsdfs(int u,int fa)
{
	L[u]=++cc;
	a[cc]=u;
	for(int i=h[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v!=fa)dfsdfs(v,u);
	}
	R[u]=++cc;
	a[cc]=u;
}
int ans; 
const int B=1700;
struct qaq{
	int l,r,i,lB,type;
	bool operator<(const qaq& b)const
	{
		return (lB==b.lB)?(((lB)&1)?r<b.r:r>b.r):l<b.l;
	}
}q[1000005];
#define rmv_Macesuted_Keai(k) ans-=!(--b[a[(k)]])
#define add_Macesuted_Keai(k) ans+=!(b[a[(k)]]++)
int vis[100005];
#define add rmv
inline void add(int x)
{
	if(vis[x])rmv_Macesuted_Keai(x);
	else add_Macesuted_Keai(x);
	vis[x]^=1;
}
#define dep depth
int main()
{
	int x, y, n = read(), m = read(),s=1, qwq = n - 1;
	iniLog(n+n + 1);
	while (qwq--)
	{
		int x=read(),y=read();
		addedge(x,y);
		addedge(y, x);
	}
	(s,0);
	dfs(s,0);
	dfsdfs(s,0);
	for(int i=1;i<=m;i++)
	{
		q[i].i=i;
		int u=read(),v=read();
		if(dep[u]>dep[v])u^=v^=u^=v;
		int lca=LCA(u,v);
		if(lca==u)
		{
			q[i].l=L[u],q[i].r=L[v],q[i].lB=q[i].l/B;
		}
		else
		{
			q[i].type=lca,q[i].l=R[u],q[i].r=L[v],q[i].lB=q[i].l/B;
		}
	}
	std::sort(q+1,q+1+m);
	register int cl=1,cr=0;
	for(register int i=1;i<=m;i++)
	{
		int &La=q[i].l,&Ra=q[i].r;
		while(cl<La)rmv(cl++);
		while(cl>La)add(--cl);
		while(cr>Ra)rmv(cr--);
		while(cr<Ra)add(++cr);
		if(q[i].type)
		{
			rmv(L[q[i].type]);
			c[q[i].i]=ans;
			rmv(L[q[i].type]);
		}
		else c[q[i].i]=ans;
	}
	for(int i=1;i<=m;i++)printf("%d\n",c[i]);
	return 0;
}
void dfs(int s, int f)
{
	*pre[s] = f, depth[s] = depth[f] + 1;
	for (int i = 1; i <= log(depth[s]); i++)pre[s][i] = pre[pre[s][i - 1]][i - 1];
	for (int i = h[s]; i; i = edge[i].p)if (edge[i].v != f)dfs(edge[i].v, s);
}
inline void swap(int &a, int &b)
{
	static int t;
	t = a, a = b, b = t;
}
#define e edge
#define d depth
int LCA(int u, int v)
{
	if (d[u] < d[v])swap(u, v);
	while (d[u] > d[v])u = pre[u][log(d[u] - d[v]) - 1];
	if (!(u^v)) return u;
	for (int q = log(depth[u]) - 1; ~q; q--)
		if (pre[u][q] ^ pre[v][q])u = pre[u][q], v = pre[v][q];
	return *pre[u];
}
2021/4/26 15:08
加载中...