蒟蒻刚学树剖,不知道为什么在查询和修改时最后一步要加一
查看原帖
蒟蒻刚学树剖,不知道为什么在查询和修改时最后一步要加一
666072
hanhoudedidue楼主2023/10/8 21:09
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
#define int long long
#define ls(x) ((x)<<1)
#define rs(x) ((x)<<1|1)
#define put putchar('\n')
using namespace std;
inline int read(){
	int f=1,x=0;char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	return f*x;
}
inline void print(int x){
	if(x>9) print(x/10);
	putchar(x%10+'0'); 
}
const int N=1e5+5;
int seg[N],top[N],n,m,op[N],siz[N],father[N],son[N],ans[N];
int rev[N],cnt,q,u[N],v[N],b[N],dep[N],s[N],t[N],tot;
vector<int> a[N];
map<pair<int,int>,int> ok; 
inline void dfs1(int x,int fa){
	b[x]=1,siz[x]=1,father[x]=fa,dep[x]=dep[fa]+1;
	for(int i=0;i<a[x].size();i++){
		if(b[a[x][i]]||a[x][i]==fa||ok[make_pair(a[x][i],x)]) continue;
		ok[make_pair(a[x][i],x)]=2;ok[make_pair(x,a[x][i])]=2;
		dfs1(a[x][i],x);
		siz[x]+=siz[a[x][i]];
		if(siz[son[x]]<siz[a[x][i]]) son[x]=a[x][i];
	}
}
inline void dfs2(int x,int topf){
	b[x]=0,seg[x]=++cnt,top[x]=topf;
	if(!son[x]) return;
	dfs2(son[x],topf);
	for(int i=0;i<a[x].size();i++){
		if(!b[a[x][i]]||ok[make_pair(x,a[x][i])]==1||father[x]==a[x][i]) continue;
		dfs2(a[x][i],a[x][i]);
	}
}
struct node{
	int l,r,sum,tag;
}tree[N<<2];
inline void build(int x,int l,int r){
	tree[x].l=l,tree[x].r=r,tree[x].sum=r-l+1,tree[x].tag=-1;
	if(l==1) tree[x].sum--;
	if(l==r) return;
	build(ls(x),l,mid);build(rs(x),mid+1,r);
}
inline void pushdown(int x){
	if(tree[x].tag!=-1){
		tree[ls(x)].tag=tree[rs(x)].tag=0;
		tree[ls(x)].sum=tree[rs(x)].sum=0;
		tree[x].tag=-1;
	}
}
inline void change(int x,int l,int r){
	if(tree[x].l>=l&&tree[x].r<=r){
		tree[x].tag=0;
		tree[x].sum=0;
		return;
	}
	if(tree[x].l>r||tree[x].r<l) return;
	pushdown(x);
	change(ls(x),l,r);change(rs(x),l,r);
	tree[x].sum=tree[ls(x)].sum+tree[rs(x)].sum;
}
inline void Change(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		change(1,seg[top[x]],seg[x]);
		x=father[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	change(1,seg[x]+1,seg[y]);
}
inline int query(int x,int l,int r){
	if(tree[x].l>=l&&tree[x].r<=r) return tree[x].sum;
	if(tree[x].l>r||tree[x].r<l) return 0;
	pushdown(x);
	return query(ls(x),l,r)+query(rs(x),l,r);
}
inline int Query(int x,int y){
	int sum=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		sum+=query(1,seg[top[x]],seg[x]);
		x=father[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	return sum+query(1,seg[x]+1,seg[y]);
}
signed main(){
	n=read(),m=read();
	for(int i=1,u,v;i<=m;i++){
		s[i]=read(),t[i]=read();
		a[s[i]].push_back(t[i]);
		a[t[i]].push_back(s[i]);
	}
	while(1){
		++q;op[q]=read();
		if(op[q]==-1) break;
		u[q]=read(),v[q]=read();
		if(op[q]==0) {
			ok[make_pair(u[q],v[q])]=1;
			ok[make_pair(v[q],u[q])]=1;
		}
	}
	dfs1(1,0);dfs2(1,1);build(1,1,n);
	for(int i=1;i<=m;i++){
		if(!ok[make_pair(s[i],t[i])]) Change(s[i],t[i]);
	}
	for(int i=q-1;i>=1;i--){
		if(op[i]==1){
			ans[++tot]=Query(u[i],v[i]);
		}
		else {
			Change(u[i],v[i]);
		}
	}
	for(int i=tot;i>=1;--i) print(ans[i]),put;
	return 0;
}
2023/10/8 21:09
加载中...