Distinct Values

Distinct Values

Problem Description

Chiaki has an array of n n positive integers. You are told some facts about the array: for every two elements ai and aj a j in the subarray al..r a l . . r ( li<jr l ≤ i < j ≤ r ), aiaj a i ≠ a j holds.
Chiaki would like to find a lexicographically minimal array which meets the facts.

Input

There are multiple test cases. The first line of input contains an integer T T , indicating the number of test cases. For each test case: The first line contains two integers n and m m (1n,m105) – the length of the array and the number of facts. Each of the next m m lines contains two integers li and ri r i ( 1lirin 1 ≤ l i ≤ r i ≤ n ). It is guaranteed that neither the sum of all n n nor the sum of all m exceeds 106 10 6 .

Output

For each test case, output n n integers denoting the lexicographically minimal array. Integers should be separated by a single space, and no extra spaces are allowed at the end of lines.

Sample Input

3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4

Sample Output

1 2
1 2 1 2
1 2 3 1 1

题目概述

不同的值

问题描述

Chiaki有一个n元正整数数组。告诉您关于数组的一些事实:对于每两个元素ai aj a j 在子数组 al..r a l . . r ( li<jr l ≤ i < j ≤ r ), aiaj a i ≠ a j 中。

Chiaki想找一个符合事实的字典上的最小数组。

输入

有多个测试用例。第一行输入包含一个整数 T T ,表示测试用例的数量。每个测试用例为:第一行包含两个整数n和m(1n,m105)———数组的长度和有几组 i i j。接下来的 m m 行包含两个整数li ri r i ( 1lirin 1 ≤ l i ≤ r i ≤ n )。保证 n n m都不超过 106 10 6

输出

对于每个测试用例,输出 n n 个整数,表示字典序上的最小数组。整数应该由一个单独的空间分隔,并且在行尾不允许有额外的空间。

样例输入

3
2 1
1 2
4 2
1 2
3 4
5 2
1 3
2 4

样例输出

1 2
1 2 1 2
1 2 3 1 1

思路

这道题意思是 要让输出的这个数组是最小的 且输入的每组i j j <script type="math/tex" id="MathJax-Element-423">j</script>表示的是a数组中的第i个数到第j个数之间不能有重复的元素
例如 我们以最后一组数据来看
5 2
1 3
2 4
说明 a数组中有5个元素 有两组i和j
这里写图片描述

因此我们可以先吧a[1]到a[n]全赋初值为1.
设一个优先队列 从首部到尾部依次是 1,2,3…….n;
我们把每组i和j,以i从小到大的顺序排列(如果两组i相同,以j从小到大排列)
观察当前组中从第i个数到第j个数中是否存在已被更新过的
如果存在被更新过的
那么将上组数据中与改组数据中未重合的部分返回优先队列即可 将该组数中与上一组数中未重合的部分 输入优先队列首部数即可
如果不存在被更新过的
则将上组数据全部返回优先队列 再输入优先队列首部数即可

代码
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

struct node
{
    int l,r;
}a[100005];     //设一结构体存每组i,j
int ans[100005];
int cmp(node a,node b)  //结构体的sort排序 
{
    if(a.l==b.l)       //如果两组i相同,以j从小到大排列
        return a.r<b.r;
    return a.l<b.l;   //以i从小到大的顺序排列
}

int main()
{
    int t,n,m;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue <int, vector<int>, greater<int> > q;//优先队列 从小到大排
        scanf("%d %d",&n,&m);
        for(int i=0;i<m;i++)
            scanf("%d %d",&a[i].l,&a[i].r);
        sort(a,a+m,cmp);
        for(int i=1;i<=n;i++)
        {
            ans[i]=1;    //将组初值都附为1
            q.push(i);   //优先队列 从首部到尾部依次是 1,2,3.......n
        }
        int l = 1, r = 0;
        for(int i=0;i<m;i++)
        {
            if(a[i].l>r)        //如果不存在被更新过的
            {
                for(int j=l;j<=r;j++)
                {
                    q.push(ans[j]);
                }
                for(int j=a[i].l;j<=a[i].r;j++)
                {
                    ans[j]=q.top();
                    q.pop();
                }
                l=a[i].l;
                r=a[i].r;
            }
            else if(a[i].r>r)         //如果存在被更新过的
            {
                for(int j=l;j<a[i].l;j++)
                {
                    q.push(ans[j]);
                }
                for(int j=r+1;j<=a[i].r;j++)
                {
                    ans[j]=q.top();
                    q.pop();
                }
                l=a[i].l;
                r=a[i].r;
            }
        }
        for(int i = 1; i <= n; i++)
                if(i == n)
                    printf("%d\n", ans[i]);
                else
                    printf("%d ", ans[i]);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值