HDU - 6301 Distinct Values 思路+优先队列

题意:

给定n段区间,要求每段区间内没有重复的数字; 构造这样一个序列,使得序列的字典序最小

思路:

字典序最小的话我们可以想到 对序列从左往右放数,从1开始放数;

然后按n个序列的左值排序,这样我们只需要考虑相邻的两个区间就好,当前区间和上一个区间,

这里分为以下情况:

    如果当前区间包含在前一个区间,则不用考虑,continue;

    如果当前区间跟前一个区间没有交集,则不需要在考虑前面的区间;

    如果有交集,则只考虑交集部分,前面不想交的部分可以忽略;

这样就产生一个怎么放数的问题,我们先用优先队列存1-n,表示当前区间可以放置的数字,再用queue按顺序存前一个区间正在用的数字,再根据上面三种情况,选择是否或者把queue中哪一部分放入优先队列;

扫描二维码关注公众号,回复: 2621997 查看本文章
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int INF = 0x7f7f7f7f;
const int maxn = 1e5 + 7;
int n, m;
int ans[maxn];
priority_queue<int, vector<int>, greater<int> > q;
queue<int> t;
struct node {
    int l, r;
}a[maxn];
bool cmp(node a, node b) {
    if(a.l == b.l) {
        return a.r > b.r;
    }
    else return (a.l<b.l);
}
int main() {
    int T; scanf("%d", &T);
    while(T--) {
        int n, m; scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; ++i) {
            ans[i] = 1;
        }
        for(int i = 0; i < m; ++i) {
            scanf("%d%d", &a[i].l, &a[i].r);
        }
        sort(a,a+m,cmp);


        while(!q.empty()) q.pop();
        while(!t.empty()) t.pop();
        for(int i = 1; i <= n; ++i) {
            q.push(i);
        }

        int xl = a[0].l, xr = a[0].r;
        for(int i = xl; i <= xr; ++i) {
            ans[i] = q.top(); q.pop();
            t.push(ans[i]);
        }

        for(int i = 1; i < m; ++i) {
            int nl = a[i].l, nr = a[i].r;
            if(nr <= xr) continue;
            else if(nl > xr) {
                while(!t.empty()) {
                    int tt = t.front(); t.pop();
                    q.push(tt);
                }
                xl = nl; xr = nr;
                for(int i = xl; i <= xr; ++i) {
                    ans[i] = q.top(); q.pop();
                    t.push(ans[i]);
                }
            }
            else {
                for(int i = xl; i < nl; ++i) {
                    int tt = t.front(); t.pop();
                    q.push(tt);
                }
                for(int i = xr+1; i <= nr; ++i) {
                    ans[i] = q.top(); q.pop();
                    t.push(ans[i]);
                }
                xl = nl; xr = nr;
            }
        }

        for(int i = 1; i <= n; ++i) {
            printf("%d%c", ans[i], (i == n?'\n':' '));
        }

    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/xiang_6/article/details/81188521