骑士之战

题目描述

有n位骑士想要通过淘汰赛决出他们当中最强大的一个。所有的骑士由1到n编号,他们总共进行了m场比赛,在第i场比赛中,所有编号在li到ri之间且尚未出局的骑士进行了一场比赛,决出了获胜者xi,其他参加比赛的骑士就出局了;我们称这些骑士被骑士xi打败了。m场比赛过后,只有一位骑士还没有出局,他就是最终的获胜者,我们希望知道其他所有骑士分别是被谁打败了。

输入

第一行包含两个正整数n和m,表示骑士和比赛的数量。

接下来m行,每行三个数l,r和x,表示参与比赛的骑士编号范围,以及获胜者的编号。

输出

输出n个由空格分隔的整数,第i个表示打败骑士i的骑士的编号。如果骑士i是获胜者,就在对应位置输出0。

样例输入

5 3
2 4 3
1 3 1
1 5 5

样例输出

5 3 1 3 0

提示

第一场比赛中,骑士3打败了骑士2和4。 第二场比赛中,骑士1打败了骑士3。 第三场比赛中,骑士5打败了骑士1。 最终的胜利者是骑士5。

对于30%的数据,n ≤ 1000;
对于100%的数据,1 ≤ m < n ≤ 3×106, 1 ≤ l ≤ x ≤ r ≤ n,保证l到r之间至少有两位尚未出局的骑士,且骑士x一定尚未出局。

分析:每次一定只剩下一个人,所以从最后一次比赛开始处理,用本轮除去x点的比赛区间去覆盖一次。用线段树处理不会超时。

也可以用链表维护。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<math.h>
#define maxn 3000000+5
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
using namespace std;
struct node
{
    int l,r,x;
}e[maxn];

int n,m,add[maxn];
int sum[maxn<<2];
void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}

void pushdown(int rt,int ln,int rn)
{
    if(add[rt])
    {
        add[rt<<1]=1;
        add[rt<<1|1]=1;

        sum[rt<<1]=sum[rt];
        sum[rt<<1|1]=sum[rt];
        add[rt]=0;
    }
}

void update(int L,int R,int C,int l,int r,int rt)
{
    if(L<=l && r<=R)
    {
        sum[rt]=C;
        add[rt]=1;
        return;
    }
    int m=(l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    if(L<=m) update(L,R,C,l,m,rt<<1);
    if(R>m) update(L,R,C,m+1,r,rt<<1|1);
    pushup(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(l==r)
    {
        return sum[rt];
    }
    int m=(l+r)>>1;
    pushdown(rt,m-l+1,r-m);
    int ans=0;
    if(L<=m) ans=query(L,R,l,m,rt<<1);
    if(R>m) ans=query(L,R,m+1,r,rt<<1|1);
    return ans;
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d",&e[i].l,&e[i].r,&e[i].x);
        if(e[i].l>e[i].r)
            swap(e[i].l,e[i].r);
    }
    for(i=m;i>=1;i--)
    {
        if(e[i].l<e[i].x) update(e[i].l,e[i].x-1,e[i].x,1,n,1);
        if(e[i].r>e[i].x) update(e[i].x+1,e[i].r,e[i].x,1,n,1);
    }
 
    printf("%d",query(1,1,1,n,1));
    for(i=2;i<=n;i++)
        printf(" %d",query(i,i,1,n,1));
    printf("\n");

    return 0;
}

    原文作者:骑士周游问题
    原文地址: https://blog.csdn.net/ToBeYours/article/details/79881597
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞