【杭电ACM多校第二场】Distinct Values(双指针+优先队列)

Distinct Values

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3894    Accepted Submission(s): 1303


 

Problem Description

Chiaki has an array of n positive integers. You are told some facts about the array: for every two elements ai and aj in the subarray al..r (l≤i<j≤r ), ai≠aj 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 , indicating the number of test cases. For each test case:

The first line contains two integers n and m (1≤n,m≤105 ) -- the length of the array and the number of facts. Each of the next m lines contains two integers li and ri (1≤li≤ri≤n ).

It is guaranteed that neither the sum of all n nor the sum of all m exceeds 106 . 

题目的大意

要求输出一个字典序最小的数列。题目给出一些区间,在这些区间里数字不能重复出现。

大致方法

结果数组ans全部初始化为1,优先队列num初始有1~n。

左、右指针均从0位置开始开始扫起。左指针扫到区间的左端点,同时将扫过的数字加入num;右指针扫到区间的右端点,同时把num.top()写入到ans......如此交替。

#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;

struct A
{
    int l,r;
    bool operator < (const A& t)
    {
        if(l!=t.l) return l < t.l;
        else return r > t.r;
    }
} a[100005];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n,len,m;
    int pl,pr;
    int ans[100005];
    priority_queue<int,vector<int>,greater<int>> num,tmp;
    for(int i=1; i<=100000; ++i)
        tmp.push(i);

    cin>>n;
    while(n--)
    {
        num = tmp;
        cin>>len>>m;
        for(int i=0; i<m; ++i)
            cin>>a[i].l>>a[i].r;
        sort(a,a+m);

        pl = pr = 1;
        for(int i=1; i<=len; ++i)
            ans[i] = 1;

        for(int i=0; i<m; ++i)
        {
            for(; pl<a[i].l; ++pl)
            {
                //cout<<"push:"<<ans[pl]<<endl;
                num.push(ans[pl]);
            }
            for(; pr<=a[i].r; ++pr)
            {
                ans[pr] = num.top();
                //cout<<"pop:"<<num.top()<<endl;
                num.pop();
            }
        }

        for(int i=1; i<=len; ++i)
        {
            cout<<ans[i];
            if(i!=len) cout<<' ';
        }
        cout<<'\n';
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/81275196