线段树+树链剖分,55pts,WA2,3,4,5,7,13,求条玄关
查看原帖
线段树+树链剖分,55pts,WA2,3,4,5,7,13,求条玄关
943076
Savior_Destroyer楼主2025/7/30 20:47
#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int N=1e5+10;

int n,m;
int head[N*2],nxt[N*2],to[N*2],tot;
int siz[N],fa[N],son[N],dep[N];
int dfn[N],cnt,no[N],top[N];

struct tr
{
	int sum;
	int tag;
};
tr tree[N*8];

void dfs1(int x)
{
	siz[x]=1;
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa[x]) continue;
		dep[y]=dep[x]+1;
		fa[y]=x;
		dfs1(y);
		siz[x]+=siz[y];
		if(siz[y]>siz[son[x]]) son[x]=y;
	}
}

void dfs2(int x,int t)
{
	dfn[x]=++cnt;
	no[cnt]=x;
	top[x]=t;
	if(son[x]) dfs2(son[x],t);
	for(int i=head[x];i;i=nxt[i])
	{
		int y=to[i];
		if(y==fa[x]) continue;
		if(y==son[x]) continue;
		dfs2(y,y);
	}
}

void add(int x,int y)
{
	nxt[++tot]=head[x];
	to[tot]=y;
	head[x]=tot;
}

void pushup(int w)
{
	int ls=2*w,rs=2*w+1;
	tree[w].sum=tree[ls].sum+tree[rs].sum;
}

void pushdown(int w,int l,int r)
{
	int ls=2*w,rs=2*w+1,mid=l+r>>1;
	tree[ls].sum+=(mid-l+1)*tree[w].tag;
	tree[ls].tag+=tree[w].tag;
	tree[rs].sum+=(r-(mid+1)+1)*tree[w].tag;
	tree[rs].tag+=tree[w].tag;
	tree[w].tag=0;
}

int sum(int w,int l,int r,int p)
{
	if(l==r) return tree[w].sum;
	if(tree[w].tag) pushdown(w,l,r);
	int mid=l+r>>1,ls=2*w,rs=2*w+1;
	if(p<=mid) return sum(ls,l,mid,p);
	else return sum(rs,mid+1,r,p);
}

void add(int w,int l,int r,int ql,int qr,int k)
{
	if(ql<=l&&qr>=r)
	{
		tree[w].sum+=(r-l+1)*k;
		tree[w].tag+=k;
		return ;
	}
	if(tree[w].tag) pushdown(w,l,r);
	int mid=l+r>>1,ls=2*w,rs=2*w+1;
	if(ql<=mid) add(ls,l,mid,ql,qr,k);
	if(qr>mid) add(rs,mid+1,r,ql,qr,k);
	pushup(w);
} 

void tree_add(int l,int r)
{
	while(top[l]!=top[r])
	{
		if(dep[top[l]]<dep[top[r]]) swap(l,r);
		add(1,1,n,dfn[top[l]],dfn[l],1);
		l=fa[top[l]];
	}
	if(dep[l]<dfn[r]) swap(l,r);
	add(1,1,n,dfn[r]+1,dfn[l],1);
}



int main()
{
	cin>>n>>m;
	for(int i=1;i<n;i++)
	{
		int x,y;
		cin>>x>>y;
		add(x,y);
		add(y,x);
	}
	dep[1]=1;
	dfs1(1);
	dfs2(1,1);
	while(m--)
	{
		char opt;
		int x,y;
		cin>>opt>>x>>y;
		if(opt=='P')
		{
			tree_add(x,y);
		}
		if(opt=='Q')
		{
			if(dep[x]>dep[y]) cout<<sum(1,1,n,dfn[x])<<endl;
			if(dep[x]<dep[y]) cout<<sum(1,1,n,dfn[y])<<endl;
		}
	}
	return 0;
}
2025/7/30 20:47
加载中...