HDU 5324 Boring Class 树套树 或 CDQ分治

来源:互联网 发布:中维网络硬盘录像机 编辑:程序博客网 时间:2024/06/11 20:54

HDU 5324 Boring Class 树套树 或 CDQ分治

题目链接:HDU 5324
题意:
给定两个序列,求一个最长的公共子序列使得第一个子序列递减,第二个递增。
思路:
将L数组的下标排序并从小到大插入,维护一个满足R的最大DP值的位置。二维。如果内存够大可以,线段树套线段树,可以用线段树套SPLAY。
代码:

#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)>>1using 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[n],data[rk[n]][1]);        ans[rk[n]]=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;}
0 0
原创粉丝点击