您的位置:首页 > 其它

HDU 5324 Boring Class 树套树 或 CDQ分治

2015-08-01 14:18 344 查看

HDU 5324 Boring Class 树套树 或 CDQ分治

题目链接:HDU 5324

题意:

给定两个序列,求一个最长的公共子序列使得第一个子序列递减,第二个递增。

思路:

将L数组的下标排序并从小到大插入,维护一个满足R的最大DP值的位置。二维。如果内存够大可以,线段树套线段树,可以用线段树套SPLAY。

代码:

[code]#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define Lson o<<1,l,mid
#define Rson o<<1|1,mid+1,r
#define MID int mid=(l+r)>>1
using namespace std;
const int maxn = 50010;
int dp[maxn];
int data[maxn][2];
int ans[maxn];
int anse;
void read(int& a){
    char c;
    while(c=getchar(),c<'0'||c>'9');
    a=c-'0';
    while(c=getchar(),c>='0'&&c<='9')
        a=a*10+c-'0';
}
int max1(int a,int b){
    if(dp[a]==dp[b])return a<b?a:b;
    return dp[a]>dp[b]?a:b;
}
namespace splay_tree{
    const int SPLAYSIZE=1501000;
    #define NIL splay_pool
    struct SNode{
        int val,mpos,pos;
        SNode *lch,*rch,*fa;
        SNode (){
            val=0;
            lch=rch=fa=0;
            pos=mpos=0;
        }
        SNode (int _val,SNode *_lch,SNode *_rch,SNode *_fa)
        :val(_val),lch(_lch),rch(_rch),fa(_fa){
            pos=mpos=0;
        }
    }splay_pool[SPLAYSIZE];
    SNode *SP;

    struct Splay{
        SNode *root,*head,*tail;
        Splay(){}
        void init(){
            head=new(++SP)SNode(-2000000000,NIL,NIL,NIL);
            tail=new(++SP)SNode(2000000000,NIL,NIL,NIL);
            head->rch=tail;
            tail->fa=head;
            root=head;
        }
        void update(SNode *t){
            if(t==NIL)return;
            t->mpos=max1(t->pos,max1(t->lch->mpos,t->rch->mpos));
        }
        void zig(SNode *t){
            SNode *f=t->fa,*c=t->rch;
            if(root==f) root=t;
            else {(f->fa->lch==f?f->fa->lch:f->fa->rch)=t;}
            t->fa=f->fa,t->rch=f, f->lch=c, f->fa=t, c->fa=f;
            update(f),update(t);
        }
        void zag(SNode *t){
            SNode *f=t->fa,*c=t->lch;
            if(root==f)root=t;
            else (f->fa->lch==f?f->fa->lch:f->fa->rch)=t;
            t->fa=f->fa,t->lch=f,f->rch=c,f->fa=t,c->fa=f;
            update(f),update(t);
        }
        void splay(SNode *&root,SNode *t){
            while(t!=root){
                if(t->fa==root){
                    if(t->fa->lch==t)zig(t);
                    else zag(t);
                }
                else {
                    if(t->fa->fa->lch==t->fa){
                        if(t->fa->lch==t)zig(t->fa),zig(t);
                        else zag(t),zig(t);
                    }
                    else {
                        if(t->fa->lch==t)zig(t),zag(t);
                        else zag(t->fa),zag(t);
                    }
                }
            }
        }
        void insert(int v,int pp){
            SNode *t=root,*p=new(++SP)SNode(v,NIL,NIL,NIL);
            p->pos=p->mpos=pp;
            while(1){
                if(t->val>p->val){
                    if(t->lch==NIL)break;
                    t=t->lch;
                }
                else {
                    if(t->rch==NIL)break;
                    t=t->rch;
                }

            }

            (t->val>p->val?t->lch:t->rch)=p,p->fa=t;

            splay(root,p);
        }
        bool lower_bound(SNode *&root,int v){
            SNode *t=root,*p=NIL;
            while(t!=NIL){
                if(t->val<v)p=t,t=t->rch;
                else t=t->lch;
            }
            if(p==NIL){
                return false;
            }
            else {
                splay(root,p);
                return true;
            }

        }
        void get(int r){
            if(anse==max1(anse,root->mpos))
                return ;
            lower_bound(root,r);
            anse=max1(root->rch->mpos,anse);
        }
    };
}
namespace SGM{
    splay_tree::Splay maxv[maxn*4];
    void quarry(int o,int l,int r,int L,int R,int val){
        if(L<=l&&r<=R){
             maxv[o].get(val);
             return;
        }
        MID;
        if(L<=mid)quarry(Lson,L,R,val);
        if(R>mid) quarry(Rson,L,R,val);
    }
    void insert(int o,int l,int r,int pos,int val){
        maxv[o].insert(val,pos);
        if(l==r) return;
        MID;
        if(pos<=mid)insert(Lson,pos,val);
        if(pos>mid) insert(Rson,pos,val);
    }
    void init(){
        dp[0]=0;
        for(int i=1;i<maxn;i++)dp[i]=1;
        splay_tree::SP=splay_tree::splay_pool;
        splay_tree::NIL->lch=splay_tree::NIL->rch=splay_tree::NIL->fa=splay_tree::NIL;
        for(int i=1;i<maxn*4;i++){
            maxv[i].init();

        }
    }
}
void init(){

}
int rk[maxn];
bool cmp(int a,int b){
    return data[a][0]>data[b][0];
}
int main(){
//    freopen("1000.in","r",stdin);
//    freopen("data.out","w",stdout);
    int n;
    while(~scanf("%d",&n)){
        init();
        for(int i=1;i<=n;i++){
            read(data[i][0]);
        }
        for(int i=1;i<=n;i++){
            read(data[i][1]);
            rk[i]=i;
        }

        sort(rk+1,rk+1+n,cmp);
        SGM::init();
        SGM::insert(1,1,n,rk
,data[rk
][1]);
        ans[rk
]=0;
        for(int i=n-1;i;i--){
            anse=0;
            SGM::quarry(1,1,n,rk[i],n,data[rk[i]][1]);
            ans[rk[i]]=anse;
            dp[rk[i]]+=dp[anse];
            SGM::insert(1,1,n,rk[i],data[rk[i]][1]);
        }
        int maxe=0;
        for(int i=1;i<=n;i++){
            if(dp[i]>dp[maxe]){
                maxe=i;
            }
        }
        printf("%d\n",dp[maxe]);
        for(int i=maxe;i;i=ans[i]){
            if(i!=maxe)putchar(' ');
            printf("%d",i);
        }
        puts("");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: