# [NOIP2013]花匠

Description

5 5 3 2 1 2

3

### 思路:{按a，b两种情况暴力dp，O(n^2),然后用权值线段树优化即可，最终复杂度O(nlogn)。}

 1 #include<iostream>
2 #include<cstdio>
3 #include<cstdlib>
4 #include<cstring>
5 #include<algorithm>
6 #define RG register
7 #define lowbit ((k)&(-k))
8 #define rs ((o<<1)|1)
9 #define ls (o<<1)
10 #define mid ((l+r)>>1)
11 #define maxx 1000003
12 #include<queue>
13 using namespace std;
14 int a[maxx],dp[maxx],sum[maxx],n,tree1[maxx*4],tree2[maxx*4];
15 void Insert1(int o,int l,int r,int p,int num){
16   if(l==r){tree1[o]=num;return;}
17   if(mid<p)Insert1(rs,mid+1,r,p,num);
18   else Insert1(ls,l,mid,p,num);
19   tree1[o]=max(tree1[rs],tree1[ls]);
20 }
21 void Insert2(int o,int l,int r,int p,int num){
22   if(l==r){tree2[o]=num;return;}
23   if(mid<p)Insert2(rs,mid+1,r,p,num);
24   else Insert2(ls,l,mid,p,num);
25   tree2[o]=max(tree2[rs],tree2[ls]);
26 }
27 int ask1(int o,int l,int r,int L,int R){
28   if(l>=L&&r<=R)return tree1[o];
32 }
33 int ask2(int o,int l,int r,int L,int R){
34   if(l>=L&&r<=R)return tree2[o];
38 }
39 int main(){
40   freopen("1.in","r",stdin);
41   freopen("1.out","w",stdout);
42   scanf("%d",&n);
43   for(RG int i=1;i<=n;++i)scanf("%d",&a[i]),a[i]++;
44   dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
46     if(Max1>Max2){
47       dp[i]=Max1+1;
48       Insert2(1,0,maxx,a[i],dp[i]);
49     }
50     else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
51   }
52   int ans=dp[n];memset(tree1,0,sizeof(tree1));memset(tree2,0,sizeof(tree2));
53   memset(dp,0,sizeof(dp));
54   dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
56     if(Max1>Max2){
57       dp[i]=Max1+1;
58       Insert2(1,0,maxx,a[i],dp[i]);
59     }
60     else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
61   }
62   ans=max(ans,dp[n]);cout<<ans;
63   return 0;
64 }

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define RG register
#define lowbit ((k)&(-k))
#define rs ((o<<1)|1)
#define ls (o<<1)
#define mid ((l+r)>>1)
#define maxx 1000003
#include<queue>
using namespace std;
int a[maxx],dp[maxx],sum[maxx],n,tree1[maxx*4],tree2[maxx*4];
void Insert1(int o,int l,int r,int p,int num){
if(l==r){tree1[o]=num;return;}
if(mid<p)Insert1(rs,mid+1,r,p,num);
else Insert1(ls,l,mid,p,num);
tree1[o]=max(tree1[rs],tree1[ls]);
}
void Insert2(int o,int l,int r,int p,int num){
if(l==r){tree2[o]=num;return;}
if(mid<p)Insert2(rs,mid+1,r,p,num);
else Insert2(ls,l,mid,p,num);
tree2[o]=max(tree2[rs],tree2[ls]);
}
int ask1(int o,int l,int r,int L,int R){
if(l>=L&&r<=R)return tree1[o];
}
int ask2(int o,int l,int r,int L,int R){
if(l>=L&&r<=R)return tree2[o];
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&n);
for(RG int i=1;i<=n;++i)scanf("%d",&a[i]),a[i]++;
dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);
if(Max1>Max2){
dp[i]=Max1+1;
Insert2(1,0,maxx,a[i],dp[i]);
}
else dp[i]=Max2+1,Insert1(1,0,maxx,a[i],dp[i]);
}
int ans=dp[n];memset(tree1,0,sizeof(tree1));memset(tree2,0,sizeof(tree2));
memset(dp,0,sizeof(dp));
dp[1]=sum[1]=1;Insert1(1,0,maxx,a[1],1);