Codeforces Round #207 (Div. 2)C. Knight Tournament(SET也可以搞定)

果7發表於2013-10-17
C. Knight Tournament
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 rihave 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.

Sample test(s)
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.



                 有感而發:當時第一題出的比較慢,但是總體還是穩住了腳。到最後才發現自己第一題寫了點小bug,結果在最後一分鐘交了一發,分數驟減,排名也掉了,rating也掉了。當時前兩題,38分鐘就過了,一直在卡第三題。但是當時思維比較短路,沒有往STL上面考慮,一直想著能用比較好的方法,最後覺得是線段樹,問了已經過了的茂茂,他說是線段樹。但是下來了發現set就可以輕鬆地A掉。腦袋轉的不靈活啊!

題目大意:題目意思是n,m,下面有m行,然後 每一行是 li ri xi,li到ri都會輸給xi,讓你輸出i號人輸給了誰,如果i沒有輸給其他人,那麼他就是最終勝利的人,輸出0.  主要就是這樣li到ri。除了xi之外,更新為xi之後其它就不需要更新了。

解題思路:現在講一下set的思路。開始把所有點都加進去,然後如果輸掉了之後就把這點刪掉,這樣想的話,很easy...

題目地址:C. Knight Tournament

AC程式碼:
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;

set <int> mq;
set <int>::iterator it,p[300005];
//p需要將開始的指標儲存,便於刪除

int res[300005];
int main()
{
    int n,m,i;
    int l,r,x;
    while(~scanf("%d%d",&n,&m))
    {
        mq.clear();
        for(i=1;i<=n;i++)
            mq.insert(i);  //先把所有的點都加進去
        while(m--)
        {
            scanf("%d%d%d",&l,&r,&x);
            it=mq.lower_bound(l);

            int tt=0;
            for(;*it<=r&&it!=mq.end();it++)
            {
                if(*it!=x)
                {
                    res[*it]=x;
                    p[tt++]=it;  //把需要刪除的指標儲存起來
                }
            }
            for(i=0;i<tt;i++)
                mq.erase(p[i]);
        }
        it=mq.begin();
        res[*it]=0;
        printf("%d",res[1]);
        for(i=2;i<=n;i++)
            printf(" %d",res[i]);
        printf("\n");
    }
    return 0;
}



相關文章