树上差分+线段树合并 (树剖LCA) 样例过了 全WA求调
查看原帖
树上差分+线段树合并 (树剖LCA) 样例过了 全WA求调
911834
bangdeng楼主2024/8/10 18:32

rt

#include <bits/stdc++.h>
#define int long long
#define TIME 1e3*clock()/CLOCKS_PER_SEC
using namespace std;
const int N=1.2e7+10,inf=1e18;
bool Mbe;
inline int read()
{
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
   		if(ch=='-')w=-1;
   		ch=getchar();
	}
    while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
    return s*w;
}
inline void write(int x)
{
    if(x<0)
	{
        putchar('-');
        x=-x;
    }
    if(x>9)write(x/10);
    putchar(x%10+'0');
}
int e[N],ne[N],h[N],idx;
void add(int a,int b)
{
	e[++idx]=b;
	ne[idx]=h[a];
	h[a]=idx;
}
int fa[N],son[N],siz[N],dep[N],top[N],dfn[N],tim;
void dfs1(int u)
{
	siz[u]=1;
	dfn[u]=++tim;
	dep[u]=dep[fa[u]]+1;
	for(int i=h[u];i;i=ne[i])
	{
		int v=e[i];
		if(v==fa[u])continue;
		fa[v]=u;dfs1(v);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])son[u]=v;
	}
}
void dfs2(int u,int t)
{
	top[u]=t;
	if(!son[u])return;
	dfs2(son[u],t);
	for(int i=h[u];i;i=ne[i])
	{
		int v=e[i];
		if(top[v])continue;
		dfs2(v,v);
	}
}
int LCA(int u,int v)
{
	while(top[u]!=top[v])
	{
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		u=fa[top[u]];
	}
	return dep[u]<dep[v]?u:v;
}
int n,ls[N],rs[N],val[N],s[N],t[N],c[N],cnt;
void push_up(int u)
{
	val[u]=val[ls[u]]+val[rs[u]]-dep[LCA(t[ls[u]],s[rs[u]])];
	s[u]=s[ls[u]]?s[ls[u]]:s[rs[u]];
	t[u]=t[rs[u]]?t[rs[u]]:t[ls[u]];
}
void update(int &u,int pos,int v,int l=1,int r=n)
{
	if(!u)u=++cnt;
	if(l==r)
	{
		c[u]+=v;val[u]=c[u]?dep[pos]:0;s[u]=t[u]=c[u]?pos:0;
		return; 
	}
	int mid=l+r>>1;
	if(dfn[pos]<=mid)update(ls[u],pos,v,l,mid);
	else update(rs[u],pos,v,mid+1,r);
	push_up(u);
}
int merge(int x,int y,int l=1,int r=n)
{
	if(!x||!y)return x|y;
	if(l==r)
	{
		c[x]+=c[y],val[x]|=val[y],s[x]|=s[y],t[x]|=t[y];
		return x;
	}
	int mid=l+r>>1;
	ls[x]=merge(ls[x],ls[y],l,mid);
	rs[x]=merge(rs[x],rs[y],mid+1,r);
	push_up(x);
	return x;
}
int root[N];
void path_add(int x,int y,int pos)
{
	int lca=LCA(x,y);
	update(root[x],pos,1);
	update(root[y],pos,1);
	update(root[lca],pos,-1);
	if(fa[lca])update(root[fa[lca]],pos,-1);
}
int ans;
void dfs(int u)
{
	for(int i=h[u];i;i=ne[i])
	{
		int v=e[i];
		if(v==fa[u])continue;
		dfs(v);
	}
	ans+=val[root[u]]-dep[LCA(s[root[u]],t[root[u]])];
	if(fa[u])root[fa[u]]=merge(root[fa[u]],root[u]);
}
int m;
bool Med;
signed main()
{
	fprintf(stderr,"%.3lf MB\n",(&Mbe-&Med)/1048576.0);
	dep[1]=1;
	n=read(),m=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		add(u,v),add(v,u);
	}
	dfs1(1),dfs2(1,1);
	while(m--)
	{
		int u=read(),v=read();
		path_add(u,v,u),path_add(u,v,v);
	}
	dfs(1);
	write(ans>>1),putchar('\n');
	cerr<<TIME<<" ms\n";
	return 0;
}
/*

*/
2024/8/10 18:32
加载中...