线段树分治求条
查看原帖
线段树分治求条
760824
MornStar楼主2024/7/6 16:21

RT 只有#1A了,剩的全WA

思路是线段树分治+可撤销并查集

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,cnt;
template<typename T,int siz> struct my_stack{
	T st[siz];
	int tp=0;
	void push(T x){st[++tp]=x;}
	void pop(){
		if(!tp)	cerr<<"THE STACK IS EMPTY!\n";
		else	tp--;
	}
	T top(){
		if(!tp)	cerr<<"THE STACK IS EMPTY!\n";
		else	return st[tp];
	}
	void clear(){tp=0;}
	bool empty(){return !tp;}
};
struct del_tmp{int num,siz,d;};
template<int N>struct DSU{
	int fa[N],siz[N],d[N];
	void clear(int n){for(int i=1;i<=n;i++)	fa[i]=i,siz[i]=1,d[i]=1;}
	int find(int x){return (fa[x]==x?x:find(fa[x]));}
	del_tmp merge(int x,int y){
		int X=find(x),Y=find(y);
		if(X==Y)	return{0,0,0};
		if(d[X]>d[Y])	swap(X,Y);
		del_tmp ret={X,siz[X],d[X]==d[Y]};
		d[Y]+=(d[X]==d[Y]),siz[Y]+=siz[X],fa[X]=Y;
		return ret;
	}
	bool same(int x,int y){return find(x)==find(y);}
};
struct edge{
	int u,v;
	friend bool operator<(edge a,edge b){return a.u<b.u;}
}e[N],q[N];
vector<int>t[N];
map<edge,int>ma;
struct segment_tree{
	DSU<N> dsu;
	my_stack<del_tmp,N<<1>st;
	segment_tree(){dsu.clear(N-1);}
	struct segment_tree_node{vector<edge>v;}t[N<<2];
	inline int ls(int x){return x<<1;};
	inline int rs(int x){return x<<1|1;};
#define mid ((l+r)>>1)
	void change(int p,int l,int r,int re_l,int re_r,edge val){
		if(re_l<=l&&r<=re_r)	return t[p].v.push_back(val),void();
		else{
			if(re_l<=mid)	change(ls(p),l,mid,re_l,re_r,val);
			if(mid<re_r)	change(rs(p),mid+1,r,re_l,re_r,val);
		}
	}
	void query(int p,int l,int r){
		//		cerr<<p<<" "<<l<<" "<<r<<"\n";
		int tp=st.tp;
		for(auto it:t[p].v)	st.push(dsu.merge(it.u,it.v));
		if(l==r){
			if(q[l].u){
				cerr<<l<<" "<<q[l].u<<" "<<q[l].v<<" "<<dsu.find(q[l].u)<<" "<<dsu.find(q[l].v)<<" "<<dsu.siz[dsu.find(q[l].u)]<<" "<<dsu.siz[dsu.find(q[l].v)]<<"\n";
				cout<<1ll*dsu.siz[dsu.find(q[l].u)]*dsu.siz[dsu.find(q[l].v)]<<"\n";
			}
		}else	query(ls(p),l,mid),query(rs(p),mid+1,r);
		while(st.tp>tp){
			del_tmp tmp=st.top();st.pop();
			if(!tmp.num)	continue;
			dsu.siz[dsu.fa[tmp.num]]-=tmp.siz;
			dsu.d[dsu.fa[tmp.num]]-=tmp.d;
			dsu.fa[tmp.num]=tmp.num;
		}
	}
}T;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin>>n>>m;
	for(int i=1,u,v;i<=m;i++){
		char opt;
		cin>>opt>>u>>v;
		if(u>v)	swap(u,v);
		if(opt=='A'){
			e[++cnt]={u,v};
			ma[{u,v}]=cnt;
			t[cnt].push_back(i);
		}else	t[ma[{u,v}]].push_back(i),q[i]={u,v};
	}
	for(int i=1;i<=cnt;i++){
		int last=0;
		t[i].push_back(m+1);
		for(auto it:t[i]){
			cerr<<it<<" ";
			if(last&&last!=m)	T.change(1,1,m,last+1,it-1,e[i]);
			last=it;
		}
		cerr<<"\n";
	}
	T.query(1,1,m);
}
2024/7/6 16:21
加载中...