Boring Class HDU - 5324 (CDQ partition)

Mr. Zstu and Mr. Hdu are taking a boring class , Mr. Zstu comes up with a problem to kill time, Mr. Hdu thinks it’s too easy, he solved it very quickly, what about you guys? 
Here is the problem: 
Give you two sequences  L1,L2,...,Ln and R1,R2,...,Rn
Your task is to find a longest subsequence v1,v2,...vm satisfies 
v11,vmn,vi<vi+1 .(for i from 1 to m - 1) 
LviLvi+1,RviRvi+1(for i from 1 to m - 1) 
If there are many longest subsequence satisfy the condition, output the sequence which has the smallest lexicographic order. 


InputThere are several test cases, each test case begins with an integer n. 
1n50000 
Both of the following two lines contain n integers describe the two sequences. 
1Li,Ri109 
OutputFor each test case ,output the an integer m indicates the length of the longest subsequence as described. 
Output m integers in the next line. 
Sample Input

5
5 4 3 2 1
6 7 8 9 10
2
1 2
3 4

Sample Output

. 5 
. 1 2. 5. 4. 3 
. 1 
. 1 

that Italy
give you two sequences Li, Ri, seeking a structure of the longest sequence, so that the decreasing L, R is incremented. Under the premise of requirements ensure maximum lexicographically smallest. (VJ)
ideas:
obviously can see a three-dimensional partial order problem.
But this question requires is the longest sequence, rather than for each element solver, so it is necessary to make the appropriate changes on the part of CDQ of partition.
We set up for each element, seeking to meet the meaning of the title sequence length it is not the beginning of the longest long. The only way to successfully find the lexicographically smallest.
Then for each element in dealing with its answer, the answer to the right of its elements should be known to the.
The traditional practice of divide and conquer obviously does not meet this requirement, because if the first rule of the left, then the right side of the unknown, you can not know the answer.
So we think of first partition on the right, then the left side of the partition.
But that was not enough, on the left in the solution process, the current answer may not be the right of a global answer, it's the reason I do not know how to describe, but in three layers CDQ which has been very obvious.
So let's divide and conquer the right, in dealing with the current level, then divide and conquer left.
Due to the special nature of the order of partition, merge sort is no longer applicable, you can only use the fast row.
Note Before treatment on the left, to restore the original order of the left.
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>

#define fuck(x) clog<<#x<<" = "<<x<<endl;
#define debug(a, x) clog<<#a<<"["<<x<<"] = "<<a[x]<<endl;
#define lson l,mid,ls
#define rson mid+1,r,rs
#define ls (rt<<1)
#define rs ((rt<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int loveisblue = 486;
const int maxn = 100086;
const int maxm = 100086;
const int inf = 0x3f3f3f3f;
const ll Inf = 999999999999999999;
const int mod = 1000000007;
const double eps = 1e-6;
const double pi = acos(-1);

int n;
struct node{
    int a,b,c,ans;
}cdq[maxn];
int mx[maxn<<2];
void update(int l,int r,int rt,int pos,int val){
    if(l==r){
        mx[rt]=val;
        return;
    }
    int mid = (l+r)>>1;
    if(pos<=mid){
        update(lson,pos,val);
    }else{
        update(rson,pos,val);
    }
    mx[rt]=max(mx[ls],mx[rs]);
}

int query(int l,int r,int rt,int L,int R){
    if(L<=l&&R>=r){
        return mx[rt];
    }
    int ans = 0;
    int mid = (l+r)>>1;
    if(L<=mid){
        ans=  max(ans,query(lson,L,R));
    }if(R>mid){
        ans = max(ans,query(rson,L,R));
    }
    return ans;
}
int num[maxn];
int rem[maxn],tot;
int get_id(int x){
    return lower_bound(rem+1,rem+1+tot,x)-rem;
}

bool cmp1(node a,node b){
    if(a.b!=b.b)return a.b>b.b;
    return a.c<b.c;
}
bool cmp(node a,node b){
    return a.a<b.a;
}

void solve(int l,int r){
    if(l==r){ return;}
    int mid = (l+r)>>1;
    solve(mid+1,r);
    int t1 = mid,t2 = r;
    int cur = r+1;
    sort(cdq+l,cdq+mid+1,cmp1);
    sort(cdq+mid+1,cdq+r+1,cmp1);
    while (t1>=l||t2>mid) {
        if (t1 < l || (t2 > mid && cdq[t1].b >= cdq[t2].b)) {
            update(1, tot, 1, get_id(cdq[t2].c), cdq[t2].ans);
            t2--;
        } else {
            cdq[t1].ans = max(cdq[t1].ans, query(1, tot, 1,  get_id(cdq[t1].c) ,tot)+1);
            t1--;
        }
    }
    for(int i=mid+1;i<=r;i++){
        update(1,tot,1,get_id(cdq[i].c),0);
    }
    sort(cdq+l,cdq+mid+1,cmp);
    solve(l,mid);
}
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
#endif
    while (scanf("%d",&n)!=EOF) {
        tot = 0;
        for (int i = 1; i <= n; i++) {
            scanf("%d", &num[i]);
        }
        for (int i = 1; i <= n; i++) {
            intx; 
            scanf ( " % d " , & x); 
            rem [ ++ all] = x; 
            CDQ [i] = {node and num [i], x, 1 }; 
        } 
        Sort (rem + 1 , rowing + 1 + all); 
        all = unique (rem + 1 , rowing + 1 + all) -rem- 1 ; 
        solve ( 1 , n); 
        Luckily (CDQ + 1 , CDQ + 1 + n cmp);
        int years = 0 ;
        for(int i=1;i<=n;i++){
            ans = max(cdq[i].ans,ans);
        }
        printf("%d\n",ans);
        int last = 0;
        cdq[0].b = inf;
        cdq[0].c = -1;
        for(int i=1;i<=n;i++){
            if(cdq[i].ans==ans&&cdq[i].b<=cdq[last].b&&cdq[i].c>=cdq[last].c){
                ans--;
                last=i;
                if(ans==0){printf("%d\n",i);}
                else printf("%d ",i);
            }
        }
    }
    return 0;
}
View Code



Guess you like

Origin www.cnblogs.com/ZGQblogs/p/11348936.html