题干:

Hooray! Berl II, the king of Berland is making a knight tournament. The king has already sent the message to all knights in the kingdom and they in turn agreed to participate in this grand event.

As for you, you're just a simple peasant. There's no surprise that you slept in this morning and were late for the tournament (it was a weekend, after all). Now you are really curious about the results of the tournament. This time the tournament in Berland went as follows:

  • There are n knights participating in the tournament. Each knight was assigned his unique number — an integer from 1 to n.
  • The tournament consisted of m fights, in the i-th fight the knights that were still in the game with numbers at least li and at most ri have fought for the right to continue taking part in the tournament.
  • After the i-th fight among all participants of the fight only one knight won — the knight number xi, he continued participating in the tournament. Other knights left the tournament.
  • The winner of the last (the m-th) fight (the knight number xm) became the winner of the tournament.

You fished out all the information about the fights from your friends. Now for each knight you want to know the name of the knight he was conquered by. We think that the knight number b was conquered by the knight number a, if there was a fight with both of these knights present and the winner was the knight number a.

Write the code that calculates for each knight, the name of the knight that beat him.

Input

The first line contains two integers nm (2 ≤ n ≤ 3·105; 1 ≤ m ≤ 3·105) — the number of knights and the number of fights. Each of the following m lines contains three integers li, ri, xi (1 ≤ li < ri ≤ nli ≤ xi ≤ ri) — the description of the i-th fight.

It is guaranteed that the input is correct and matches the problem statement. It is guaranteed that at least two knights took part in each battle.

Output

Print n integers. If the i-th knight lost, then the i-th number should equal the number of the knight that beat the knight number i. If the i-th knight is the winner, then the i-th number must equal 0.

Examples

Input

4 3
1 2 1
1 3 3
1 4 4

Output

3 1 4 0 

Input

8 4
3 5 4
3 7 6
2 8 8
1 8 1

Output

0 8 4 6 4 8 6 1 

Note

Consider the first test case. Knights 1 and 2 fought the first fight and knight 1 won. Knights 1 and 3 fought the second fight and knight 3 won. The last fight was between knights 3 and 4, knight 4 won.

题目大意:

第一行输入n,m,n表示有n个人(标号1~n),m表示有m 场战斗,接下来m行,每行输入l , r , x  ,表示标号从l 到 r的人进行了一场战斗,其中x (l<=x<=r) 为最后的胜利者,即x杀死了该场战斗中的其它人,那么在下一场 战斗中死了的人不再进入战斗;要求输出杀死每一个人的直接凶手的标号,最后活着的那个人的输出标号为0;

解题报告:

     这题第一想法就是set啊、、直接nlogn就搞完了。。不过其实这题当做并查集区间合并的例子再合适不过了。。就跟codeforce371D一样,,这题也可以用并查集来实现合并的操作。。而且也不算难。下面分别放上代码。

AC代码:(set)

#include<bits/stdc++.h>

using namespace std;

const int MAX = 4*1e5;
int f[MAX];
int ans[MAX];
set<int > ss;
int getf(int u) {
	return u==f[u] ? u : f[u]=getf(f[u]);
}
void merge(int u,int v,int win) {
	if(win == u) {
		ans[v]=u;
		f[v]=u;
	}
	else {
		ans[u] = v;
		f[u] = v;
	}
}
int main()
{
	int n,m;//n个骑士,m场比赛 
	int u,v,win;
	set<int > :: iterator it,itt;
	cin>>n>>m;
	for(int i = 1; i<=MAX - 1; i++) {
		f[i] = i;
	}
	for(int i = 1; i<=n; i++) {
		ss.insert(i);
	}
	while(m--) {
		scanf("%d %d %d",&u,&v,&win);
		if(ss.find(u) != ss.end() ) it = ss.find(u);
		else it = ss.lower_bound(u);
		for(; it!=ss.end();) {
			if((*it) == win ) {
				it++;
				continue;
			}
			if(*it>v) break;
			ans[(*it)]=win;
			itt=it;
			it++;
			ss.erase(itt);
		}
	}
	for(int i = 1; i<=n; i++) {
		printf("%d ",ans[i]);	
	} 
	return 0 ;
}

放上最初的关于set的一些操作的演示的代码:

#include<bits/stdc++.h>

using namespace std;

const int MAX = 4*1e5;
bool bk[MAX];//用来记录是否比过赛,如果没比过那就直接记录了。如果比过了那就找getf。 
int f[MAX];
int ans[MAX];
vector<int > vc;
set<int > ss;
int getf(int u) {
	return u==f[u] ? u : f[u]=getf(f[u]);
}
void merge(int u,int v,int win) {
	if(win == u) {
		ans[v]=u;
		f[v]=u;
	}
	else {
		ans[u] = v;
		f[u] = v;
	}
}
int main()
{
	int n,m;//n个骑士,m场比赛 
	int u,v,win;
	set<int > :: iterator it,itt;
	cin>>n>>m;
//	cout<<ss.empty()<<endl;	
//	ss.insert(5);
//	ss.insert(2);
//	it=ss.find(2);
//	ss.erase(2);
//	it++;
//	cout<<*it<<endl;	
//	for(it = ss.begin(); it!=ss.end(); it++) {
//		printf("%d ",*it);
////		ss.
//	}
////	cout<<*it<<endl;
//	getchar();
	for(int i = 1; i<=MAX - 1; i++) {
		f[i] = i;
	}
	for(int i = 1; i<=n; i++) {
//		vc.push_back(i);
		ss.insert(i);
	}
	
//	for(it = ss.begin(); it!=ss.end(); it++) {
//		printf("%d ",*it);
//	}
	while(m--) {
		scanf("%d %d %d",&u,&v,&win);
		if(ss.find(u) != ss.end() ) it = ss.find(u);
		else it = ss.lower_bound(u);
		for(; it!=ss.end();) {
			if((*it) == win ) {
				it++;
				continue;
			}
			if(*it>v) break;
			ans[(*it)]=win;
			itt=it;
			it++;
			ss.erase(itt);
		}
	}
	for(int i = 1; i<=n; i++) {
		printf("%d ",ans[i]);	
	} 
	return 0 ;
}

放上第一次写并查集的代码:

#include<bits/stdc++.h>

using namespace std;

const int MAX = 4*1e5;
int f[MAX],ne[MAX];
int ans[MAX];
set<int > ss;
int getf(int u) {
	return u==f[u] ? u : f[u]=getf(f[u]);
}
void merge(int u,int v,int win) {
	if(win == u) {
		ans[v]=u;
		f[v]=u;
	}
	else {
		ans[u] = v;
		f[u] = v;
	}
}
int main()
{
	int n,m;//n个骑士,m场比赛 
	int u,v,win;
	set<int > :: iterator it,itt;
	cin>>n>>m;
	for(int i = 1; i<=MAX - 1; i++) {
		ans[i]=i;f[i] = i;ne[i]=i+1;
	}

	while(m--) {
		int tmp;
		scanf("%d %d %d",&u,&v,&win);
		/*
		for(int i=u;i<=v;i=tmp)
		{
			if(ans[i]==i)
			ans[i]=win;
			tmp=ne[i];
			if(i<win)
			{
				ne[i]=win;
			}
			else
			{
				ne[i]=v+1;
			 } 
		}
		*/
		
		
		for(int i = u;i<win; i=tmp) {
			if(ans[i]==i) ans[i] = win;
			tmp = ne[i];
//			merge(i-1,i);
			ne[i] = ne[win-1];
		}		
		for(int i = win;i<=v; i=tmp) {
			if(ans[i]==i) ans[i] = win;
			tmp = ne[i];
//			merge(i-1,i);
			ne[i] = ne[v];
		}
		
		
		/*
		for(int i = u+1;i<=win-1; i=tmp) {
			if(ans[i-1]==i-1) ans[i-1] = win;
			tmp = ne[i];
//			merge(i-1,i);
			ne[i] = ne[win-1];
		}
		if(ans[win-1]==win-1) ans[win-1] = win;
		
		for(int i = win+1;i<=v; i=tmp) {
			if(ans[i-1]==i-1) ans[i-1] = win;
			tmp = ne[i];
//			merge(i-1,i);
			ne[i] = ne[v];
		}
		if(ans[v]==v) ans[v] = win;
		*/
		if(m==0)ans[win]=0;
	}
	for(int i = 1; i<=n; i++) {
		printf("%d ",ans[i]);	
	} 
	return 0 ;
}

伤痕累累的代码、、、

其实那个ne[i] = ne[win-1];可以直接ne[i] = win;  的

然后,化简一下就成了这样:

#include<bits/stdc++.h>

using namespace std;

const int MAX = 4*1e5;
int f[MAX],ne[MAX];
int ans[MAX];
int main() {
	int n,m;//n个骑士,m场比赛
	int u,v,win;
	cin>>n>>m;
	for(int i = 1; i<=MAX - 1; i++) {
		ans[i]=i;
		ne[i]=i+1;
	}

	while(m--) {
		int tmp;
		scanf("%d %d %d",&u,&v,&win);
		for(int i=u; i<=v; i=tmp) {
			if(ans[i]==i) ans[i]=win;
			tmp=ne[i];
			if(i<win) ne[i]=win;
			else ne[i]=v+1;
		}
		if(ans[v]==v) ans[v] = win;
		if(m==0)ans[win]=0;
	}
	for(int i = 1; i<=n; i++) {
		printf("%d ",ans[i]);
	}
	return 0 ;
}

区间合并这个根本没用到merge和getf、、其实你只是直接体现在代码中了,比如if(ans[i]==i) ans[i]=win,,这不就是merge吗。。都让这个区间等于win。