[HDU6301]Distinct Values【模拟】

6301 Distinct Values

这题是因为实在没事干了,我就随意打了一下,结果就A掉了。

想法很简单,用堆维护在这个区间没有出现过最小数(因为我们要字典序最小,肯定要越高位越小,所以肯定先放小的数),我们可以将区间全部投射到一维的数组上,然后枚举这个位置,肯定选择最大的这个覆盖区间,放置这个区间中没有的最小的数。

然后我们考虑区间转移,比如说当前区间结束了,那么当前区间的左边界到下一区间的左边界上的点肯定不会对当前造成影响,所以完全可以选择这段区间里的数。放到小根堆中就可以了。

#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int T,n,m,Len,hep_Num[100005],Len_Num,Len_L,que[100005];
bool hsh[100005];
struct xcw{
    int x,id;bool f;
    bool operator <(const xcw b)const{return x<b.x;}
}a[200005],hep_L[200005];
int read(){
    int ret=0;char ch=getchar();bool f=1;
    for(;!isdigit(ch);ch=getchar()) f^=!(ch^'-');
    for(; isdigit(ch);ch=getchar()) ret=(ret<<1)+(ret<<3)+ch-48;
    return f?ret:-ret;
}
void put_Num(int x){
    hep_Num[++Len_Num]=-x;
    push_heap(hep_Num+1,hep_Num+1+Len_Num);
}
int get_Num(){
    pop_heap(hep_Num+1,hep_Num+1+Len_Num);
    return -hep_Num[Len_Num--];
}
void put_L(xcw x){
    hep_L[++Len_L]=x;
    push_heap(hep_L+1,hep_L+1+Len_L);
}
xcw get_L(){
    pop_heap(hep_L+1,hep_L+1+Len_L);
    return hep_L[Len_L--];
}
int main(){
    for(T=read();T;T--){
        memset(hsh,0,sizeof(hsh));
        while(Len_Num) get_Num();
        while(Len_L) get_L();
        n=read();m=read();
        for(int i=1;i<=m;i++) a[(i<<1)-1]=(xcw){read(),i,1},a[i<<1]=(xcw){read()+1,i,0};
        sort(a+1,a+1+(m<<=1));
        for(int i=1;i<=n;i++) put_Num(i);
        for(int i=1,j=1;i<=n;i++){
            while(a[j].x==i&&j<=m){
                if(a[j].f) hsh[a[j].id]=1,put_L((xcw){-a[j].x,a[j].id,0});
                else hsh[a[j].id]=0;
                j++;
            }
            if(Len_L==0) printf("1"),que[i]=1;
            else{
                xcw Now=get_L();int P=-Now.x;
                while(!hsh[Now.id]&&Len_L) Now=get_L();
                if(hsh[Now.id]){
                    put_L(Now);
                    for(int j=P;j<-Now.x;j++) put_Num(que[j]);
                    que[i]=get_Num();
                }else{
                    for(int j=P;j<i;j++) put_Num(que[j]);
                    que[i]=1;
                }
                printf("%d",que[i]);
            }
            printf(i==n?"\n":" ");
        }
    }
    return 0;
}

转载于:https://www.cnblogs.com/XSamsara/p/9838827.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值