[WOJ4379] 飘雪圣域 [主席树]

传送门

每次询问点的个数是r-l+1, 那么联通块个数就是总点数减去边的个数

考虑哪些边有贡献, 令边为l,r (l

有时静态区间, 然后就是主席树


#include
#define N 200050
using namespace std;
struct Node{int ls,rs,val;}t[N*40]; 
int tot,rt[N];
vector v[N];
int n,q;
void Build(int &x,int l,int r){
	x = ++tot;
	if(l==r) return;
	int mid = (l+r) >> 1;
	Build(t[x].ls, l, mid);
	Build(t[x].rs, mid+1, r);
}
void Insert(int &x,int last,int l,int r,int pos){
	x = ++tot; t[x] = t[last]; t[x].val++;
	if(l==r) return;
	int mid = (l+r) >> 1;
	if(pos<=mid) Insert(t[x].ls, t[last].ls, l, mid, pos);
	else Insert(t[x].rs, t[last].rs, mid+1, r, pos);
}
int Quary(int a,int b,int l,int r,int L,int R){
	if(L<=l && r<=R) return t[a].val - t[b].val;
	int mid = (l+r) >> 1, ans = 0;
	if(L<=mid) ans += Quary(t[a].ls, t[b].ls, l, mid, L, R);
	if(R>mid) ans += Quary(t[a].rs, t[b].rs, mid+1, r, L, R);
	return ans; 
} 
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;iy) swap(x,y);
		v[x].push_back(y);
	}
	Build(rt[0], 1, n);
	for(int i=1;i<=n;i++){
		rt[i] = rt[i-1];
		if(!v[i].size()) continue;
		for(int j=0;j

 

你可能感兴趣的:(主席树)