CodeForces - 356A Knight Tournament(区间合并)

本文详细解析了CodeForces 356A题目的解题思路,采用区间合并的方法,避免了直接暴力遍历的超时问题。通过使用f[]数组存储答案和Next[]数组实现区间合并,有效地解决了3e5规模的人和决斗问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://codeforces.com/problemset/problem/356/A

题意:给n个人和m次决斗,每次决斗表示 [ l , r ] 区间内的每人都被 x 打败,最后输出每个人被谁打败,最后的赢家输出0。

思路:这一题有3e5个人和3e5次决斗,直接暴力一遍一定会超时,所以可以考虑用区间合并的思想来做这道题。首先开两个一维数组,f[] 数组用来存答案,Next[]数组来实现区间合并。初始化时f[i] = i , Next[i] = i+1;

之后就是关键的区间合并啦。
每当我们读入一组 l , r , x 时,我们把[ l , r ]分成两段 [l , x-1] 和 [x , r];
然后用for循环每次更新 f[i] 和 Next[i] ,左侧Next[i] = x , 右侧Next[i] = Next[r];
用 i = Next[i] 来跳过已经更新过 f[i] 的点。

如果还不是很理解的话,我建议读者可以用两个区间来模拟一下 Next[] 数组值的变化。
毕竟我语言功底较差,望见谅。

具体代码如下:

#include<iostream>
#include<cstdio>

using namespace std;

const int maxn=3e5+7;

int f[maxn],Next[maxn],vis[maxn];

int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        //初始化
        for(int i=1; i<=n; i++)
        {
            f[i]=i;
            Next[i]=i+1;
            vis[i]=0;
        }

        while(m--)
        {
            int l,r,x;
            scanf("%d%d%d",&l,&r,&x);
            //更新左侧
            for(int i=l; i<x;)
            {
                if(vis[i]==0&&i!=x)
                {
                    vis[i]=1;
                    f[i]=x;
                }
                int t=i;
                i=Next[i];
                Next[t]=x;
            }
            //更新右侧
            for(int i=x; i<=r;)
            {
                if(vis[i]==0&&i!=x)
                {
                    vis[i]=1;
                    f[i]=x;
                }
                int t=i;
                i=Next[i];
                Next[t]=Next[r];
            }
        }

        for(int i=1; i<=n; i++)
        {
            if(i!=1) printf(" ");
            if(f[i]==i) printf("0");
            else printf("%d",f[i]);
        }
        puts("");

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值