#线段树,倒序#CF356A Knight Tournament

题目


分析

要求覆盖必须是第一个覆盖的,
考虑最后一个覆盖的很简单做线段树区间赋值,
那么倒序区间赋值就可以了


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
const int N=300011;
struct rec{int l,r,x;}q[N];
int w[N<<2],n,m;
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
inline void update(int k,int l,int r,int x,int y,int z){
	if (l==x&&r==y) {w[k]=z; return;}
	rr int mid=(l+r)>>1;
	if (w[k]) w[k<<1]=w[k<<1|1]=w[k],w[k]=0;
	if (y<=mid) update(k<<1,l,mid,x,y,z);
	else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
	    else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
}
inline void query(int k,int l,int r){
	if (l==r) {print(w[k]),putchar(32); return;}
	rr int mid=(l+r)>>1;
	if (w[k]) w[k<<1]=w[k<<1|1]=w[k],w[k]=0;
	query(k<<1,l,mid);
	query(k<<1|1,mid+1,r);
}
signed main(){
	n=iut(); m=iut();
	for (rr int i=1;i<=m;++i) q[i]=(rec){iut(),iut(),iut()};
	for (rr int i=m;i;--i){
		if (q[i].l<q[i].x) update(1,1,n,q[i].l,q[i].x-1,q[i].x);
		if (q[i].x<q[i].r) update(1,1,n,q[i].x+1,q[i].r,q[i].x);
	}
	query(1,1,n);
	return 0;
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14109993.html