loj2056 "TJOI / HEOI2016" sequence

When I hadn't learned cdq yet, I wrote the code orzzz
ref of the tree cover tree on luogu.

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, uu, vv, dp[100005], c[100005];
struct Node{
    int val, zxz, zdz, idx;
}nd[100005], tmp[100005];
bool cmpzxz(Node x, Node y){
    return x.zxz<y.zxz;
}
bool cmpidx(Node x, Node y){
    return x.idx<y.idx;
}
int lb(int x){
    return x&-x;
}
void add(int x, int v){
    for(; x<=100000; x+=lb(x))
        c[x] = max(c[x], v);
}
int query(int x){
    int re=0;
    for(; x; x-=lb(x))
        re = max(re, c[x]);
    return re;
}
void clr(int x){
    for(; x<=100000; x+=lb(x))
        c[x] = 0;
}
void cdq(int l, int r){
    if(l==r)    return ;
    int mid=(l+r)>>1;
    cdq(l, mid);
    sort(nd+mid+1, nd+r+1, cmpzxz);
    int qaq=l;
    for(int i=mid+1; i<=r; i++){
        while(qaq<=mid && nd[qaq].val<=nd[i].zxz){
            add(nd[qaq].zdz, dp[nd[qaq].idx]);
            qaq++;
        }
        dp[nd[i].idx] = max(dp[nd[i].idx], query(nd[i].val)+1);
    }
    for(int i=l; i<qaq; i++)    clr(nd[i].zdz);
    sort(nd+mid+1, nd+r+1, cmpidx);
    cdq(mid+1, r);
    int jj=l, kk=mid+1;
    for(int i=l; i<=r; i++)
        if(jj<=mid && (kk>r || nd[jj].val<=nd[kk].val)) tmp[i] = nd[jj++];
        else    tmp[i] = nd[kk++];
    for(int i=l; i<=r; i++)
        nd[i] = tmp[i];
}
int main(){
    cin>>n>>m;
    for(int i=1; i<=n; i++){
        scanf("%d", &nd[i].val);
        nd[i].zdz = nd[i].zxz = nd[i].val;
        nd[i].idx = i;
        dp[i] = 1;
    }
    for(int i=1; i<=m; i++){
        scanf("%d %d", &uu, &vv);
        nd[uu].zdz = max(nd[uu].zdz, vv);
        nd[uu].zxz = min(nd[uu].zxz, vv);
    }
    cdq(1, n);
    int ans=0;
    for(int i=1; i<=n; i++)
        ans = max(ans, dp[i]);
    cout<<ans<<endl;
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325237492&siteId=291194637