%%% PoPoQQQ :http://blog.csdn.net/popoqqq/article/details/44962711
“第一问CDQ分治裸上
第二问用每个元素所在的LIS个数/总LIS个数就是答案
每个元素所在的LIS自己必选,然后统计前面的方案数和后面的方案数
以前面的方案数为例,令f[x]为以x结尾的LIS长度,那么有DP方程:
g[i]=Σg[j] (f[j]+1=f[i],j<i,a[j].x<a[i].x,a[j].y<a[i].y)
将所有元素按f值排序,分层DP,每层DP是一个三维偏序,上CDQ分治再搞搞就好了”
#include<cstdio> #include<cstdlib> #include<algorithm> using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } int ans; int n,h[50005],v[50005]; int f[50005]; int sx[100005],icnt; inline int Bin(int x){ return lower_bound(sx+1,sx+icnt+1,x)-sx; } namespace CDQ{ namespace BIT{ #define lowbit(x) ((x)&-(x)) int maxn; int c[100005]; inline void init(int n){ maxn=n; } inline void add(int x,int r){ for (int i=x;i<=maxn;i+=lowbit(i)) c[i]=max(c[i],r); } inline void clr(int x){ for (int i=x;i<=maxn;i+=lowbit(i)) c[i]=0; } inline int sum(int x){ int ret=0; for (int i=x;i;i-=lowbit(i)) ret=max(ret,c[i]); return ret; } } struct event{ int x,y; int idx; bool operator < (const event &B) const{ return x==B.x?y<B.y:x<B.x; } }eve[50005],tmp[50005]; inline void cdq(int l,int r){ if (l==r) return; int mid=(l+r)>>1; cdq(l,mid); for (int i=l;i<=r;i++) tmp[i]=eve[i]; sort(eve+l,eve+mid+1); sort(eve+mid+1,eve+r+1); int i=l,j=mid+1; while (j<=r) { while (i<=mid && eve[i].x<=eve[j].x) BIT::add(eve[i].y,f[eve[i].idx]),i++; f[eve[j].idx]=max(f[eve[j].idx],BIT::sum(eve[j].y)+1); j++; } for(int j=l;j<i;j++) BIT::clr(eve[j].y); for (int i=l;i<=r;i++) eve[i]=tmp[i]; cdq(mid+1,r); } inline void Solve(){ BIT::init(icnt); for (int i=1;i<=n;i++) eve[i].idx=i,eve[i].x=Bin(h[i]),eve[i].y=Bin(v[i]),f[i]=1; cdq(1,n); ans=0; for (int i=1;i<=n;i++) ans=max(ans,f[i]); printf("%d\n",ans); } } namespace BIT{ #define lowbit(x) ((x)&-(x)) int maxn; double c[100005]; inline void init(int n){ maxn=n; } inline void add(int x,double r){ for (int i=x;i<=maxn;i+=lowbit(i)) c[i]+=r; } inline void clr(int x){ for (int i=x;i<=maxn;i+=lowbit(i)) c[i]=0; } inline double sum(int x){ double ret=0; for (int i=x;i;i-=lowbit(i)) ret+=c[i]; return ret; } inline double sum(int l,int r){ return sum(r)-sum(l-1); } } struct event{ int f,x,y; int idx; }eve[50005],itmp[50005],tmp[50005]; double tot,pre[50005],nxt[50005],Ans[50005]; int L[50005],R[50005]; bool cmpidx(event A,event B){ return A.idx<B.idx; } bool cmpxy(event A,event B){ return A.x==B.x?A.y<B.y:A.x<B.x; } bool cmpf(event A,event B){ return A.f<B.f; } inline void cdq1(int l,int r,int k){ if (l==r) return; int mid=(l+r)>>1; cdq1(l,mid,k); cdq1(mid+1,r,k); sort(eve+l,eve+mid+1,cmpxy); sort(eve+mid+1,eve+r+1,cmpxy); int i=l,j=mid+1; while(j<=r) { while(i<=mid&&eve[i].x<=eve[j].x) { if (eve[i].f==k-1) BIT::add(eve[i].y,pre[eve[i].idx]); i++; } if (eve[j].f==k) pre[eve[j].idx]+=BIT::sum(eve[j].y); j++; } for(int j=l;j<i;j++) if (eve[j].f==k-1) BIT::clr(eve[j].y); } inline void cdq2(int l,int r,int k){ if (l==r) return; int mid=(l+r)>>1; cdq2(l,mid,k); cdq2(mid+1,r,k); sort(eve+l,eve+mid+1,cmpxy); sort(eve+mid+1,eve+r+1,cmpxy); int i=r,j=mid; while(j>=l) { while(i>=mid+1 && eve[i].x>=eve[j].x) { if (eve[i].f==k) BIT::add(eve[i].y,nxt[eve[i].idx]); i--; } if (eve[j].f==k-1) nxt[eve[j].idx]+=BIT::sum(eve[j].y,icnt); j--; } for(int j=r;j>i;j--) if (eve[j].f==k) BIT::clr(eve[j].y); } int main() { freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); for (int i=1;i<=n;i++) read(h[i]),read(v[i]),sx[++icnt]=h[i],sx[++icnt]=v[i]; reverse(h+1,h+n+1); reverse(v+1,v+n+1); sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; CDQ::Solve(); BIT::init(icnt); for (int i=1;i<=n;i++) eve[i].f=f[i],eve[i].idx=i,eve[i].x=Bin(h[i]),eve[i].y=Bin(v[i]); sort(eve+1,eve+n+1,cmpf); for (int i=1;i<=ans;i++) L[i]=n+1,R[i]=0; for (int i=1;i<=n;i++) L[eve[i].f]=min(L[eve[i].f],i),R[eve[i].f]=max(R[eve[i].f],i); for (int i=L[1];i<=R[1];i++) pre[eve[i].idx]=1; for (int i=2;i<=ans;i++) { for (int j=L[i-1];j<=R[i];j++) itmp[j]=eve[j]; sort(eve+L[i-1],eve+R[i]+1,cmpidx); cdq1(L[i-1],R[i],i); for (int j=L[i-1];j<=R[i];j++) eve[j]=itmp[j]; } for (int i=L[ans];i<=R[ans];i++) nxt[eve[i].idx]=1; for (int i=ans;i>=2;i--) { for (int j=L[i-1];j<=R[i];j++) itmp[j]=eve[j]; sort(eve+L[i-1],eve+R[i]+1,cmpidx); cdq2(L[i-1],R[i],i); for (int j=L[i-1];j<=R[i];j++) eve[j]=itmp[j]; } for (int i=1;i<=n;i++) if (f[i]==ans) tot+=pre[i]; tot=0; for (int i=1;i<=n;i++) if (f[i]==1) tot+=nxt[i]; for (int i=n;i;i--) printf("%.5lf%c",Ans[i]=pre[i]*nxt[i]/tot,i==1?'\n':' '); return 0; }