G - 01Sequence(贪心&dsu)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了G - 01Sequence(贪心&dsu)相关的知识,希望对你有一定的参考价值。

G - 01Sequence(贪心&dsu)

区间按右端点排序,每次靠右填,填的时候用dsu快速找到最近的 0 0 0

查询的话用BIT维护即可。

每个位置最多被填一次,时间复杂度: O ( m l o g m + n l o g n ) O(mlogm+nlogn) O(mlogm+nlogn)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int n,m;
struct node{
	int x,y,z;
	bool operator<(const node &a)const{
		return y<a.y;
	}
}a[N];
struct BIT{
	#define lowbit(x) x&(-x)
	#define il inline
	ll s[N];
	int n;
	il void upd(int x,int v){
		while(x<=n){
			s[x]+=v;x+=lowbit(x);
		}return;
	}
	il ll que(int x){
		ll ans=0;
		while(x){
			ans+=s[x];x-=lowbit(x);
		}return ans;
	}
}T;
int s[N];
int find(int x){return x==s[x]?x:s[x]=find(s[x]);}
void Init(int n){
	for(int i=1;i<=n;i++) s[i]=i;
}
int ans[N];
int main(){
	scanf("%d%d",&n,&m);Init(n);T.n=n;
	rep(i,1,m) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
	sort(a+1,a+m+1);
	rep(i,1,m){
		ll sum=T.que(a[i].y)-T.que(a[i].x-1);
		if(sum>=a[i].z) continue;
		a[i].z-=sum;
		for(int j=find(a[i].y);j>=a[i].x&&a[i].z;j=find(j)){
			T.upd(j,1);a[i].z--;ans[j]=1;
			s[j]=j-1;
		} 
	}
	rep(i,1,n) printf("%d ",ans[i]);
	return 0;
}

以上是关于G - 01Sequence(贪心&dsu)的主要内容,如果未能解决你的问题,请参考以下文章

[探究] dsu on tree,一类树上离线问题的做法

E. Binary Matrix(dsu&滚动)

G - Two Merged Sequences(dp&贪心)

G - Two Merged Sequences(dp&贪心)

C - Safe Distance(二分&DSU)

F. SUM and REPLACE(线段树&dsu)