题解——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 ;
}