[HEOI 2016] seq

题解:

发现多决策且明显无后效性,果断dp,那么转移方程F[i]=F[j]+1

设R[I]为改变之后的最大值,L[i]为改变之后的最小值

由于只能改变一个元素 所以转移的条件是 (j<i && R[j]<a[i] && a[j]<L[i]) 写成这样 就光然大悟 裸三维偏序诶

于是CDQ 乱搞即可 人懒不想打归并...

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <cmath>
 7 using namespace std;
 8 const int N=100005,INF=2e8;
 9 int gi(){
10     int str=0;char ch=getchar();
11     while(ch>'9' || ch<'0')ch=getchar();
12     while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();
13     return str;
14 }
15 int n,m,f[N];
16 struct node{
17     int x,L,R,id;
18 }a[N];
19 bool compid(const node &px,const node &qx){
20     return px.id<qx.id;
21 }
22 bool compL(const node &px,const node &qx){
23     return px.L<qx.L;
24 }
25 bool compx(const node &px,const node &qx){
26     return px.x<qx.x;
27 }
28 int Tree[N<<1],st[N<<1],top=0;
29 void add(int sta,int x){
30     for(int i=sta;i<=n;i+=(i&(-i))){if(x>Tree[i])Tree[i]=x;}
31 }
32 int query(int sta){
33     int ret=0;
34     for(int i=sta;i>=1;i-=(i&(-i)))if(Tree[i]>ret)ret=Tree[i];
35     return ret;
36 }
37 void Clear(int sta){
38     for(int i=sta;i<=n;i+=(i&(-i)))Tree[i]=0;
39 }
40 int ans=0;
41 void cdq(int l,int r){
42     if(l==r)return ;
43     int mid=(l+r)>>1;
44     cdq(l,mid);
45     sort(a+l,a+mid+1,compx);sort(a+mid+1,a+r+1,compL);
46     int t1=l,t2=mid+1;
47     while(t1<=mid && t2<=r){
48         if(a[t1].x<=a[t2].L)st[++top]=a[t1].R,add(a[t1].R,f[a[t1].id]),t1++;
49         else f[a[t2].id]=max(f[a[t2].id],query(a[t2].x)+1),t2++;
50     }
51     while(t2<=r){
52         f[a[t2].id]=max(f[a[t2].id],query(a[t2].x)+1);t2++;
53     }
54     while(top)Clear(st[top--]);
55     sort(a+mid+1,a+r+1,compid);
56     cdq(mid+1,r);
57 }
58 void work(){
59     int x,y;
60     n=gi();m=gi();
61     for(int i=1;i<=n;i++)a[i].x=gi(),a[i].L=a[i].R=a[i].x,a[i].id=i,f[i]=1;
62     for(int i=1;i<=m;i++){
63         x=gi();y=gi();
64         if(y>a[x].R)a[x].R=y;
65         if(y<a[x].L)a[x].L=y;
66     }
67     cdq(1,n);
68     for(int i=1;i<=n;i++)if(f[i]>ans)ans=f[i];
69     printf("%d
",ans);
70 }
71 int main()
72 {
73     freopen("heoi2016_seq.in","r",stdin);
74     freopen("heoi2016_seq.out","w",stdout);
75     work();
76     return 0;
77 }
原文地址:https://www.cnblogs.com/Yuzao/p/7198057.html