HDU 多校对抗赛 D Distinct Values

Distinct Values

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


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 (li<jr), aiajholds.
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 (1n,m105) -- the length of the array and the number of facts. Each of the next m lines contains two integers li and ri(1lirin).

It is guaranteed that neither the sum of all n nor the sum of all m exceeds 106.
 
Output
For each test case, output  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
 

题意:你需要构造一个长度为n的字典序最小的序列,要求如下

   1,有m个区间,在这些区间内,数字不得重复

   2,长度为n,不能有0出现

题解:既然要求字典序最小,那么我们那些没有被区间覆盖的地方一定是1

   区间覆盖的地方得特殊考虑,区间是否相交(重叠)等问题

   于是我们先把区间按照左端点排序,每次在区间内放尽可能小的就行

   格式要求行尾不能有多余的空格

代码如下

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
struct node{
  int l,r;
}a[maxn];
bool cmp(node a,node b){
  if(a.l==b.l) return a.r<b.r;
  return a.l<b.l;
}
int ans[maxn];
int vis[maxn];
int main(){
  int T;
  scanf("%d",&T);
  while(T--){
    int n,m;
    memset(vis,0,sizeof(vis));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
      scanf("%d%d",&a[i].l,&a[i].r);
    }
    sort(a+1,a+m+1,cmp);
    priority_queue<int,vector<int>,greater<int> >q;
        for(int i=1; i<=n; i++){
            ans[i]=1;vis[i]=0;
            q.push(i);
        }
        int l=a[1].l,r=a[1].l;
        for(int i=1;i<=m;i++){
            for(;l<a[i].l;l++){
                if(vis[l]) q.push(ans[l]);
            }
            for(;r<=a[i].r;r++){
                if(r>=a[i].l){
                    ans[r]=q.top();q.pop();
                    vis[r]=1;
                }
            }
        }
        for(int i=1; i<=n; i++) {
            printf("%d",ans[i]);
            if(i==n) printf("\n");
            else printf(" ");
        }
  }
}
View Code

猜你喜欢

转载自www.cnblogs.com/buerdepepeqi/p/9358294.html