YbtOJ 高效进阶 并查集 H. 3.染色操作

题面
洛谷版,数据更水
做法:

  • 我会线段树!
    写这玩意不是在自虐吗?
    此处贴上我们wjy同学的做法:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+10;
int n,m;
struct segment_tree
{
	#define mid ((l+r)>>1)
	#define ls (k<<1)
	#define rs (k<<1|1)
	struct node{int v,laz;}f[N<<2];
	void pushup(int k){f[k] = {f[ls].v+f[rs].v,f[k].laz};}
	void pushdown(int k,int l,int r)
	{
		if(!f[k].laz||l==r)return f[k].laz = 0,void();
		f[ls].laz = f[k].laz,f[rs].laz = f[k].laz;
		f[ls].v = 0,f[rs].v = 0;
		f[k].laz = 0;
	}
	void init(int k,int l,int r)
	{
		if(l==r)return f[k] = {1,0},void();
		init(ls,l,mid),init(rs,mid+1,r);
		pushup(k);
	}
	void modify(int k,int l,int r,int x,int y)
	{
		if(x<=l&&r<=y)return f[k] = {0,1},void();
		pushdown(k,l,r);
		if(x<=mid)modify(ls,l,mid,x,y);
		if(mid<y)modify(rs,mid+1,r,x,y);
		pushup(k);
	}
	int query(){return f[1].v;}
}st;
int main()
{
	scanf("%d%d",&n,&m);
	st.init(1,1,n);
	for(int i = 1,l,r;i<=m;i++)
	{
		scanf("%d%d",&l,&r);
		st.modify(1,1,n,l,r);
		printf("%d\n",st.query());
	}
	return 0;
}
  • 我会并查集!
    书上的做法,不知道是怎么想出来的。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000001;
int fa[MAXN];
int find(int x) {
    if (fa[x] == 0)
        return x;
    return fa[x] = find(fa[x]);
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int s = n;
    while (m--) {
        int l, r;
        scanf("%d%d", &l, &r);
        for (int i = find(l); i <= r; i = find(i)) {
            fa[i] = i + 1;
            s--;
        }
        printf("%d\n", s);
    }

    return 0;
}
  • 我会ODT!
    我的做法,较线段树简单,较并查集直接。
#include<bits/stdc++.h>
using namespace std;
using ODT=map<int,bool>;
int tot,l,r,n,m;
ODT odt;
void split(int l){
	odt[l]=prev(odt.upper_bound(l))->second;
}
void assign(int l,int r,bool v){
	split(l);split(r+1);
	auto it=odt.find(l),end=odt.find(r+1);
	while(it!=end){
		int x=it->first;
		bool y=it->second;
		it=odt.erase(it);
		if(y&&!v)tot-=it->first-x;
	}
	odt[l]=v;
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> m;
	tot=n;
	odt[1]=1;
	odt[n+1]=0;
	while(m--){
		cin >> l >> r;
		assign(l,r,0);
		cout << tot << '\n';
	}
	return 0;
}
posted @ 2025-08-29 15:00  NotMonika  阅读(18)  评论(0)    收藏  举报