题解——CF356A Knight Tournament(倒叙维护)

题解——CF356A Knight Tournament(倒叙维护)

快扶ssw02起来,ssw02还能水紫题

欢迎转载ssw02的博客:https://www.cnblogs.com/ssw02/p/11837626.html

题面

题目大意):有n个骑士,他们每个人都被从1-n进行编号,他们现在需要进行一次比赛,且总共会进行m场比赛。每场比赛会在编号在Li-Ri这段区间内的骑士之间举行,对于每场比赛,它的胜利者的编号为Xi,其他的骑士会出局,之后无法进行比赛。最后留下的骑士就是这次比赛的最终胜利者。比赛结束后,每个骑士都想知道他被哪一个骑士击败了,请你告诉他们。

输入格式

第一行为两个整数n,m。代表有n个骑士参加m场比赛;

之后的m行,每行3个整数Li,Ri,Xi,代表第i场比赛在编号在Li-Ri之间的骑士举行,胜利者的编号为Xi。

保证输入数据正确,保证至少有两名骑士参加每一场战斗;

输出格式

输出只有一行,包括n个整数,第i个数代表第i个骑士被编号为第i个数的骑士打败,特别的,如果第i个骑士是最后的胜者,输出0;

思路

是不是和一道洛谷题库首页的黄题有点像??

很快想到,每个人被打败,之和他第一次覆盖有关,之后的覆盖对其无效 。 反过来说 , 就是倒叙维护区间推平 , 不断覆盖 , 得到最早的值即可 。 对于任意一段[L,R] , col 的区间 , 拆分为[ L , col-1 ] , [ col+1 , R ] ,注意判断,避免死循环 、

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 300005 ;  
inline int read(){
	int s=0 ; char g=getchar() ; while( g>'9'||g<'0' )g=getchar() ; 
	while( g>='0'&&g<='9' )s=s*10+g-'0',g=getchar() ; return s ;  
}
int N , M ; 
struct ap{
	int  l , r , col ; 
}t[MAXN<<2] , q[MAXN] ;
void  build( int p , int l , int r ){
	t[p].l = l , t[p].r = r ;
	if( l == r ){
		t[p].col = l ;  return  ; 
	}
	int mid = ( l+r )>>1 ; 
	build( p<<1 , l , mid ) , build( p<<1|1 , mid+1 , r ) ;
	if( t[p<<1].col != t[p<<1|1].col )t[p].col = 0 ; 
	else t[p].col = t[p<<1].col ;  
}
inline void spread( int p ){
	if( t[p].col == 0 )return ; 
	t[p<<1].col = t[p<<1|1].col  = t[p].col ; 
}
void  change( int p , int l , int r , int val ){
	if( l <= t[p].l && t[p].r <= r ){
	    t[p].col = val ; return ; 	
	}
	spread( p ) ;
	int mid = (t[p].l+t[p].r)>>1 ; 
	if( l <= mid )change( p<<1 , l , r , val ) ; 
	if( r > mid )change( p<<1|1 , l , r , val ) ; 
	if( t[p<<1].col != t[p<<1|1].col )t[p].col = 0 ; 
	else t[p].col = t[p<<1].col ; 
}
void  print( int p ){
	if( t[p].l == t[p].r ){
		if( t[p].col == t[p].l )printf("0 ");
		else printf("%d ",t[p].col) ;
		return ;
	}
	spread(p) ; 
	print(p<<1) , print(p<<1|1) ;
}
int main(){
	N = read() , M = read() ;
	for( register int i = 1 ; i <= M ; ++i )
		q[i].l = read() , q[i].r = read() , q[i].col = read()  ;
	build( 1 , 1 , N ) ; 
	while( M ){
		if( q[M].l < q[M].col )change( 1 , q[M].l , q[M].col-1 , q[M].col ) ;
		if( q[M].r > q[M].col )change( 1 , q[M].col+1 , q[M].r , q[M].col ) ;  
		M-- ; 
	}
	print(1) ;
	return 0 ; 
}
posted @ 2019-11-11 19:26  蓝银杏-SSW  阅读(237)  评论(0编辑  收藏  举报
//结束