[BZOJ1852] [MexicoOI06] The maximum length decreasing sequence of
I do not know the amount of water is not the past. . . And another one online solution to problem filmed, but beat it out. . .
Consider the following greedy
(I turn to consider the question, that is, to satisfy \ (A_i> \ max_ J = {1} ^ {J <B_j {i}} \) )
According to \ (B \) sorted values for each \ (I \) recording the maximum \ (B \) is (B_i \) \ optimal solution \ (Max_i \) (Note that this is in fact too tired prefix and of)
Then consider each \ (i \) , we force it to generate contributions, to find the last previous \ (B_j <A_i \) , connected (Max_j \) \ back
Because doing so will skip the middle of this period, but in fact they may generate contributions, so I consider them connected \ (i \) of the back can be set up
Is seeking \ (\ left | \ lbrace a_k> B_i, {k \ in [J + 1, i-1]} \ rbrace \ right | \) , the Chairman of the tree we can get discrete +
So get an answer \ (max_n \) (the code is \ (dp \) array ..)
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define reg register
typedef long long ll;
#define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
inline void cmax(int &a,int b){ ((a<b)&&(a=b));}
inline void cmin(int &a,int b){ ((a>b)&&(a=b));}
char IO;
int rd(){
int s=0,f=0;
while(!isdigit(IO=getchar())) f|=(IO=='-');
do s=(s<<1)+(s<<3)+(IO^'0');
while(isdigit(IO=getchar()));
return f?-s:s;
}
const int N=2e5+10,K=15;
const int R=1e5;
int n;
struct Node{
int a,b;
bool operator < (const Node __) const {
return b<__.b;
}
}A[N];
int h[N],hc;
int dp[N];
int rt[N*K],s[N*K],ls[N*K],rs[N*K],cnt;
void Add(int p,int pre,int l,int r,int x) {
s[p]=s[pre]+1;
if(l==r) return;
int mid=(l+r)>>1;
ls[p]=ls[pre],rs[p]=rs[pre];
x<=mid?Add(ls[p]=++cnt,ls[pre],l,mid,x):Add(rs[p]=++cnt,rs[pre],mid+1,r,x);
}
int Que(int pl,int pr,int l,int r,int ql,int qr) {
if(ql>qr) return 0;
if(ql==l&&qr==r) return s[pr]-s[pl];
int mid=(l+r)>>1;
if(qr<=mid) return Que(ls[pl],ls[pr],l,mid,ql,qr);
else if(ql>mid) return Que(rs[pl],rs[pr],mid+1,r,ql,qr);
else return Que(ls[pl],ls[pr],l,mid,ql,mid)+Que(rs[pl],rs[pr],mid+1,r,mid+1,qr);
}
int main(){
rep(i,1,n=rd()) {
A[i].a=rd(),A[i].b=rd();
h[++hc]=A[i].a,h[++hc]=A[i].b;
}
sort(h+1,h+hc+1),hc=unique(h+1,h+hc+1)-h-1;
sort(A+1,A+n+1);
rep(i,1,n) {
A[i].a=lower_bound(h+1,h+hc+1,A[i].a)-h;
A[i].b=lower_bound(h+1,h+hc+1,A[i].b)-h;
Add(rt[i]=++cnt,rt[i-1],1,hc,A[i].a);
}
rep(i,1,n) {
int l=1,r=i-1,res=0;
while(l<=r) {
int mid=(l+r)>>1;
if(A[mid].b<A[i].a) l=mid+1,res=mid;
else r=mid-1;
}
dp[i]=max(dp[i-1],dp[res]+1+Que(rt[res],rt[i-1],1,hc,A[i].b+1,hc));
}
int ans=dp[n];
printf("%d\n",ans);
}