zoukankan      html  css  js  c++  java
  • 【好题】线段树+贪心+思维——cf1248F

    位置的嵌套把我弄晕了。。。总感觉多写了一层

    /*
    首先要找到一种满足条件的排列方式
    给所有段按(左端点,右端点)升序排序,然后分配位置
        从左到右扫描位置i,把左端点<i的所有Seg放入优先队列 
        优先队列每次取出右端点最小的
         
    然后考虑两个段是否可以交换顺序:设段[l,r]被分配的位置是x    
        那么和他交换的段位置只能在[l,x-1],[x+1,r]里找,只要找到[l,x-1]位置右端点最大值,[x+1,r]位置左端点最小值
        判能否越过x即可 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 200005
    
    int n;
    struct Seg{
        int l,r,id;
        bool operator>(Seg a)const {
            return r>a.r;
        }
    }s[N],ss[N];
    int cmp(Seg a,Seg b){return a.l<b.l;}
    
    priority_queue<Seg,vector<Seg>,greater<Seg> >pq; 
    int ans1[N],ans2[N],tmp[N];
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    int mx[N<<2],mi[N<<2];
    void update1(int pos,int id,int l,int r,int rt){
        if(l==r){mx[rt]=id;return;}
        int m=l+r>>1;
        if(pos<=m)update1(pos,id,lson);
        else update1(pos,id,rson);
        
        if(!mx[rt<<1]){
            mx[rt]=mx[rt<<1|1];return;
        }
        if(!mx[rt<<1|1]){
            mx[rt]=mx[rt<<1];return;
        }
        int id1=mx[rt<<1],id2=mx[rt<<1|1];
        if(ss[id1].r>=ss[id2].r)mx[rt]=id1;
        else mx[rt]=id2; 
    }
    int query1(int L,int R,int l,int r,int rt){
        if(L>R)return 0;
        if(L<=l && R>=r)return mx[rt];
        int m=l+r>>1,res=0;
        if(L<=m)res=query1(L,R,lson);
        if(R>m){
            if(!res)res=query1(L,R,rson);
            else {
                int res2=query1(L,R,rson);
                if(ss[res].r<ss[res2].r)res=res2;
            }
        }
        return res;
    }
    
    void update2(int pos,int id,int l,int r,int rt){
        if(l==r){mi[rt]=id;return;}
        int m=l+r>>1;
        if(pos<=m)update2(pos,id,lson);
        else update2(pos,id,rson);
        
        if(!mi[rt<<1]){
            mi[rt]=mi[rt<<1|1];return;
        }
        if(!mi[rt<<1|1]){
            mi[rt]=mi[rt<<1];return;
        }
        int id1=mi[rt<<1],id2=mi[rt<<1|1];
        if(ss[id1].l<=ss[id2].l)mi[rt]=id1;
        else mi[rt]=id2; 
    }
    int query2(int L,int R,int l,int r,int rt){
        if(L>R)return 0;
        if(L<=l && R>=r)return mi[rt];
        int m=l+r>>1,res=0;
        if(L<=m)res=query2(L,R,lson);
        if(R>m){
            if(!res)res=query2(L,R,rson);
            else {
                int res2=query2(L,R,rson);
                if(ss[res].l>ss[res2].l)res=res2;
            }
        }
        return res;
    }
    int pos[N];
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>s[i].l>>s[i].r;
            s[i].id=i;
        }
        memcpy(ss,s,sizeof s);
        sort(s+1,s+1+n,cmp);
        
        int p=1;
        for(int i=1;i<=n;i++){
            while(p<=n && s[p].l<=i){
                pq.push(s[p]);
                ++p;
            }
            Seg now=pq.top();pq.pop();
            ans1[i]=now.id;
        }
        //for(int i=1;i<=n;i++)pos[ans[i].id]=i;
    
        for(int i=1;i<=n;i++){
            update1(i,ans1[i],1,n,1);
            update2(i,ans1[i],1,n,1);
        }    
        int flag=0,p1,p2;
        memcpy(ans2,ans1,sizeof ans1);
        for(int i=1;i<=n;i++){
            int L1=ss[ans1[i]].l,R1=i-1;
            int L2=i+1,R2=ss[ans1[i]].r;
            int res1=query1(L1,R1,1,n,1);
            int res2=query2(L2,R2,1,n,1);
            if(res1 && ss[res1].r>=i){
                flag=1;
                p1=ans1[i],p2=res1;
                break;    
            }
            if(res2 && ss[res2].l<=i){
                flag=1;
                p1=ans1[i],p2=res2;
                break;
            }
        }
        if(flag){
            puts("NO");
            for(int i=1;i<=n;i++)
                tmp[ans1[i]]=i;
            for(int i=1;i<=n;i++)cout<<tmp[i]<<" ";
            puts("");
            swap(tmp[p1],tmp[p2]);//1 4 2 3
            for(int i=1;i<=n;i++)cout<<tmp[i]<<" ";
            puts("");
        }else {
            puts("YES");
                for(int i=1;i<=n;i++)
                tmp[ans1[i]]=i;
            for(int i=1;i<=n;i++)cout<<tmp[i]<<" ";
            puts("");
        }
    } 
  • 相关阅读:
    “大型票务系统”和“实物电商系统”在恶意订单方面的差别与联系
    Eclipse_java项目中导入外部jar文件
    03007_JDBC概述
    微笑心灵“医”路 -- 09级临床医学雷林鹏访谈实录
    雷林鹏:一个90后草根创业者的野蛮生长
    关于hugepages 3.txt
    人物专访:全面发展的企业家——雷林鹏
    热备模式相关问题2.txt
    农林苗木人物专访:雷林鹏 追求本质
    热备模式相关问题2.txt
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12891909.html
Copyright © 2011-2022 走看看