2018杭電多校day1_D Distinct Values HDU - 6301

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

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

It is guaranteed that neither the sum of all nnnor the sum of all mm exceeds 106106. 

Output

For each test case, output nn 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

 

這個題是我們做的時候做的第四個題,因爲看到這個題過人數還是比較多,而且題意也很簡單,我們大概在這個題上磨了剩餘的所有時間。emmm還是太菜了。

題意:給一個長度爲n的序列,m個限制,每個限制給定L,R在每個詢問區間(L,R)內每個數字都不相同,然後找字典序最小的序列。

思路:貪心

對於左端點爲i的區間,只保留右端點最大的那個。

對於左端點爲i+1的區間,他的最大右端點只有在比i的最大右端點大的時候纔會保留。

之後就用優先隊列或者set模擬貪心過程即可。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m,l[100005],r[100005],ans[100005];
priority_queue<int, vector<int>, greater<int>> q;
void swap(int &a,int &b){
    int t=a;
    a=b;
    b=t;
}
void qsort(int L,int R){
    int i=L,j=R,xl=l[(L+R)>>1],xr=r[(L+R)>>1];
    do{
        while(l[i]<xl||(l[i]==xl&&r[i]>xr)) i++;
        while(l[j]>xl||(l[j]==xl&&r[j]<xr)) j--;
        if(i<=j){
            swap(l[i],l[j]);
            swap(r[i],r[j]);
            i++;
            j--;
        }
    }while(i<=j);
    if(L<j) qsort(L,j);
    if(i<R) qsort(i,R);
}
int min(int a,int b){
    if(a<b) return a;
    return b;
}
int max(int a,int b){
    if(a>b) return a;
    return b;
}
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++) scanf("%d%d",&l[i],&r[i]);
        qsort(1,m);
        while(!q.empty()) q.pop();
        for(int i=1;i<=n;i++){
            q.push(i);
            ans[i]=1;
        }
        int last=0;
        for(int i=1;i<=m;i++){
            if(last!=0&&r[last]>=r[i]) continue;
            if(last!=0){
                for(int j=l[last];j<=min(r[last],l[i]-1);j++){
                    q.push(ans[j]);
                }
                for(int j=max(r[last]+1,l[i]);j<=r[i];j++){
                    ans[j]=q.top();
                    q.pop();
                }
            }else{
                for(int j=l[i];j<=r[i];j++){
                    ans[j]=q.top();
                    q.pop();
                }
            }
            last=i;
        }
        for(int i=1;i<n;i++) printf("%d ",ans[i]);
        printf("%d\n",ans[n]);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章