树剖 dfs部分神奇RE
查看原帖
树剖 dfs部分神奇RE
578590
Inui_Sana楼主2022/7/15 06:46

rt,对着洛谷板子改过,基本上没区别,但是在第一次dfs的时候就re。求调

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<queue>
#define run int T;scanf("%d",&T);while(T--)solve
#define lb lower_bound
using namespace std;
typedef long long ll;
const int maxn=2e5+7,inf=2147483647;
const int mod=1;
int n,m,e[maxn<<2],tag[maxn<<2];
int siz[maxn],wt[maxn],dep[maxn],fa[maxn];
int cnt,dfn[maxn],rk[maxn],top[maxn];
int tot,head[maxn];
int x,y,z,ans;
bool vis[maxn];
struct node{
	int to,nxt;
}edge[maxn];
void add(int u,int v){
	edge[++tot]={v,head[u]};
	head[u]=tot;
}
void dfs1(int now){
//	return;
	siz[now]=1;
	for(int i=head[now];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(v!=fa[now]){
			fa[v]=now;
			dep[v]=dep[now]+1;
			dfs1(v);
			siz[now]+=siz[v];
			if(siz[v]>=siz[wt[now]])wt[now]=v;
		}
	}
}
void dfs2(int now,int t){
	dfn[now]=++cnt;
	rk[cnt]=now;
	top[now]=t;
	if(!wt[now])return;
	dfs2(wt[now],t);
	for(int i=head[now];i;i=edge[i].nxt){
		int v=edge[i].to;
		if(v!=fa[now]&&v!=wt[now])dfs2(v,v);
	}
}
inline void pushup(int now){e[now]=e[now<<1]+e[now<<1|1];}
inline void pushdown(int l,int r,int now){
	if(!tag[now])return;
	int mid=l+r>>1;
	tag[now<<1]+=tag[now];tag[now<<1|1]+=tag[now];
	e[now<<1]+=(mid-l+1)*tag[now];e[now<<1|1]+=(r-mid)*tag[now];
	tag[now]=0;
}
void update(int l,int r,int now){
	if(l>=x&&r<=y){
		e[now]+=r-l+1;
		tag[now]++;
		return;
	}
	pushdown(l,r,now);
	int mid=l+r>>1;
	if(x<=mid)update(l,mid,now<<1);
	if(y>mid)update(mid+1,r,now<<1|1);
	pushup(now);
}
void query(int l,int r,int now){
	if(l>=x&&r<=y){
		ans+=e[now];
		return;
	}
	pushdown(l,r,now);
	int mid=l+r>>1;
	if(x<=mid)query(l,mid,now<<1);
	if(y>mid)query(mid+1,r,now<<1|1);
}
void change(int l,int r){
//	cout<<top[l]<<top[r]<<endl;
	while(top[l]!=top[r]){
		if(dep[top[l]]<dep[top[r]])swap(l,r);
		x=dfn[top[l]]-1,y=dfn[l]-1;
		update(1,n,1);
		l=fa[top[l]];
	}
	if(dep[l]>dep[r])swap(l,r);
	x=dfn[l],y=dfn[r]-1;
	update(1,n,1);
}
void ask(int l,int r){
	while(top[l]!=top[r]){
		if(dep[top[l]]<dep[top[r]])swap(l,r);
		x=dfn[top[l]]-1,y=dfn[l]-1;
		query(1,n,1);
		l=fa[top[l]];
	}
//	cout<<l<<r<<endl;
	if(dep[l]>dep[r])swap(l,r);
	x=dfn[l],y=dfn[r]-1;
	query(1,n,1);
}
signed main(){
//	freopen("P3038_4.in","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1,u,v;i<n;i++){
		scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
	}
	dep[1]=1;
	dfs1(1);dfs2(1,1);
	for(int i=1;i<=m;i++){
		char op=getchar();
		while(op!='P'&&op!='Q')op=getchar();
		scanf("%d%d",&x,&y);
		if(op=='Q'){
			ans=0;
			ask(x,y);
			printf("%d\n",ans);
		}else{
			change(x,y);
		}
	}
}

请忽略我看错题把单点查询打成区间查询

2022/7/15 06:46
加载中...