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

 

优化代码SELECT SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND is_new_customer = 1, 1, 0)) AS new_customer_count, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND is_new_customer = 0, 1, 0)) AS old_customer_count, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND is_new_customer = 1, payment_amount, 0)) AS new_customer_payment_amount, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND is_new_customer = 0, payment_amount, 0)) AS old_customer_payment_amount, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND category = 'A', 1, 0)) AS category_A_customer_count, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND category = 'A', payment_amount, 0)) AS category_A_payment_amount, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND category = 'B', 1, 0)) AS category_B_customer_count, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND category = 'B', payment_amount, 0)) AS category_B_payment_amount, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND product_id = 'P1', 1, 0)) AS product_P1_customer_count, SUM(IF(order_date BETWEEN '2022-10-31' AND '2022-11-11' AND product_id = 'P1', payment_amount, 0)) AS product_P1_payment_amount FROM orders o LEFT JOIN (SELECT DISTINCT order_date FROM orders WHERE order_date BETWEEN '2022-10-31' AND '2022-11-11') d1 ON o.order_date = d1.order_date LEFT JOIN (SELECT DISTINCT order_date FROM orders WHERE order_date BETWEEN '2021-10-31' AND '2022-10-30' AND order_date NOT IN (SELECT order_date FROM orders WHERE order_date BETWEEN '2022-10-31' AND '2022-11-11')) d2 ON o.order_date = d2.order_date LEFT JOIN (SELECT DISTINCT order_date FROM orders WHERE order_date BETWEEN '2021-11-12' AND '2022-10-30' AND order_date IN (SELECT order_date FROM orders WHERE order_date BETWEEN '2022-10-31' AND '2022-11-11')) d3 ON o.order_date = d3.order_date WHERE d1.order_date IS NOT NULL OR d2.order_date IS NOT NULL OR d3.order_date IS NOT NULL;
最新发布
05-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值