【洛谷P4093】 [HEOI2016/TJOI2016]序列 CDQ分治+动态规划

你发现只会改变一个位置,所以可以直接进行dp 

具体转移的话用 CDQ 分治转移就好了~

#include <bits/stdc++.h>    
#define N  100006   
#define setIO(s) freopen(s".in","r",stdin)  
using namespace std; 
int n,m;   
int C[N],f[N];  
int lowbit(int t) 
{
    return t&(-t); 
} 
void CL(int x) 
{ 
    while(x<N) C[x]=0, x+=lowbit(x); 
}  
void add(int x,int v) 
{
    while(x<N) C[x]=max(C[x],v), x+=lowbit(x);    
} 
int query(int x) 
{
    int re=0; 
    while(x)  re=max(re,C[x]), x-=lowbit(x); 
    return re;   
}
struct node
{
    int val,id,mn,mx; 
}a[N];  
bool cmp1(node a,node b) 
{
    return a.id<b.id;  
}
bool cmp2(node a,node b) 
{   
    return a.val<b.val;  
}
int cmp3(node a,node b) 
{ 
    return a.mn<b.mn; 
} 
void solve(int l,int r) 
{
    if(l>=r) return; 
    int mid=(l+r)>>1;   
    solve(l,mid);  
    sort(a+l,a+1+mid,cmp2);    sort(a+mid+1,a+1+r,cmp3);      
    for(int i=mid+1,j=l;i<=r;++i) 
    {
        while(a[j].val<=a[i].mn&&j<=mid)  add(a[j].mx,f[a[j].id]),++j;   
        f[a[i].id]=max(f[a[i].id], query(a[i].val)+1);         
    }
    for(int i=l;i<=mid;++i)    CL(a[i].mx);    
    sort(a+mid+1,a+r+1,cmp1), solve(mid+1,r); 
}
int main() 
{  
    //setIO("input"); 
    int i,j,re=0; 
    scanf("%d%d",&n,&m); 
    for(i=1;i<=n;++i)  f[i]=1, scanf("%d",&a[i].val),a[i].id=i,a[i].mn=a[i].mx=a[i].val;   
    for(i=1;i<=m;++i) 
    {
        int x,y; 
        scanf("%d%d",&x,&y);   
        a[x].mn=min(a[x].mn, y); 
        a[x].mx=max(a[x].mx, y);   
    }
    solve(1,n); 
    for(i=1;i<=n;++i)   re=max(re,f[i]); 
    printf("%d\n",re); 
    return 0; 
}

  

posted @ 2019-11-28 12:02  EM-LGH  阅读(130)  评论(0编辑  收藏  举报