码迷,mamicode.com
首页 > 编程语言 > 详细

HDU - 5324:Boring Class (CDQ分治&树状数组&最小字典序)

时间:2018-11-06 00:50:13      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:怎么   表示   using   void   sort   its   i++   update   ret   

题意:给定N个组合,每个组合有a和b,现在求最长序列,满足a不升,b不降。

思路:三位偏序,CDQ分治。   但是没想到怎么输出最小字典序,我好菜啊。 

最小字典序: 我们倒序CDQ分治,ans[i]表示倒序的以i为结尾的最长序列,如果当前的ans[i]==目前最大,而且满足序列要求,就输出。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=50010;
int q[maxn],Mx[maxn],x[maxn],y[maxn],b[maxn],tot,ans[maxn],res;
bool cmp(int w,int v){ if(y[w]==y[v]) return w<v;return y[w]<y[v];}
int query(int x){int res=0; while(x){ res=max(res,Mx[x]);x-=(-x)&x;} return res;}
void add(int x,int y){while(x<=tot){ Mx[x]=max(y,Mx[x]);x+=(-x)&x; }}
void update(int x){while(x<=tot){ Mx[x]=0;x+=(-x)&x;}}
void cdq(int L,int R)
{

    if(L==R) { ans[L]=max(ans[L],1); return ;}
    int Mid=(L+R)>>1;
    cdq(Mid+1,R);
    int num=0; rep(i,L,R) q[++num]=i;
    sort(q+1,q+num+1,cmp);
    for(int i=num;i>=1;i--){
        if(q[i]>Mid) add(x[q[i]],ans[q[i]]);
        else ans[q[i]]=max(ans[q[i]],query(x[q[i]])+1);
    }
    for(int i=num;i>=1;i--)
      if(q[i]>Mid) update(x[q[i]]);
    cdq(L,Mid);
}
int main()
{
    int N;
    while(~scanf("%d",&N)){
        rep(i,1,N) Mx[i]=ans[i]=0; res=0;
        rep(i,1,N) scanf("%d",&x[i]),b[i]=x[i];
        rep(i,1,N) scanf("%d",&y[i]);
        sort(b+1,b+N+1);
        tot=unique(b+1,b+N+1)-(b+1);
        rep(i,1,N) x[i]=lower_bound(b+1,b+tot+1,x[i])-b;
        cdq(1,N);
        rep(i,1,N) res=max(res,ans[i]);
        printf("%d\n",res);
        int X,Y; tot=res;
        rep(i,1,N){
            if(ans[i]==tot){
                if(tot==res) {
                    X=x[i]; Y=y[i]; tot--;
                    printf("%d",i);
                }
                else if(x[i]<=X&&y[i]>=Y){
                    X=x[i]; Y=y[i]; tot--;
                    printf(" %d",i);
                }
            }
        }
        puts("");
    }
    return 0;
}

 

HDU - 5324:Boring Class (CDQ分治&树状数组&最小字典序)

标签:怎么   表示   using   void   sort   its   i++   update   ret   

原文地址:https://www.cnblogs.com/hua-dong/p/9912247.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!