2018杭电多校day1_D HDU - 6301

版权声明:随便写写,也不重要,欢迎挑错讨论 https://blog.csdn.net/qq_37305947/article/details/81487031

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;
}

猜你喜欢

转载自blog.csdn.net/qq_37305947/article/details/81487031
今日推荐