Acdream 1126 Beautiful People(最长上升子序列,dp+线段树优化)
来源:互联网 发布:网络推广框架协议 编辑:程序博客网 时间:2024/05/16 12:25
先按x排序,对于相同的x分块处理,也就是x相同的一起处理。dp[i]=dp[j]+1,由于x相同是一起处理所以只要a[i]>a[j]即可。
建议先看一下本博客里的LIS线段树优化的文章。
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;struct pi{ int x; int y; int id;}pp[100005];int a[100005];int dp[100005];int b[100005];int cmp(pi a,pi b){ if(a.x!=b.x) return a.x<b.x; return a.y<b.y;}int get(int x,int y,int n){ int le,ri,mid; le=1; ri=n; while(le<=ri){ mid=(le+ri)/2; if(pp[b[mid]].y<y&&pp[b[mid]].x<x) le=mid+1; else ri=mid-1; } return le;}struct ppi{ int le; int ri; int max; int m;}pp1[400005];void build(int tot,int l,int r){ pp1[tot].le=l; pp1[tot].ri=r; pp1[tot].max=0; pp1[tot].m=-1; if(l==r) return ; build(2*tot,l,(l+r)/2); build(2*tot+1,(l+r)/2+1,r);}void merg(int tot,int p,int m,int id){ if(pp1[tot].le==pp1[tot].ri){ if(pp1[tot].max<m){ pp1[tot].max=m; pp1[tot].m=id; } return ; } int mid; mid=(pp1[tot].le+pp1[tot].ri)/2; if(p<=mid){ merg(2*tot,p,m,id); } else{ merg(2*tot+1,p,m,id); } if(pp1[2*tot].max<pp1[2*tot+1].max){ pp1[tot].max=pp1[2*tot+1].max; pp1[tot].m=pp1[2*tot+1].m; } else{ pp1[tot].max=pp1[2*tot].max; pp1[tot].m=pp1[2*tot].m; }}int query(int tot,int n){ if(pp1[tot].le>=1&&pp1[tot].ri<=n){ return pp1[tot].m; } int x,y; int mid; mid=(pp1[tot].le+pp1[tot].ri)/2; x=-1; y=-1; x=query(2*tot,n); if(n>mid){ y=query(2*tot+1,n); } if(x==-1) return y; if(y==-1) return x; if(dp[x]<dp[y]) return y; return x;}int main(){ int i,n,m,k,p,tot,j,f; while(cin>>n){ tot=0; for(i=1;i<=n;i++){ scanf("%d%d",&pp[i].x,&pp[i].y); pp[i].id=i; b[++tot]=pp[i].y; } sort(pp+1,pp+1+n,cmp); sort(b+1,b+tot+1); m=tot; build(1,1,m); for(i=1;i<=n;i++){ p=i; while(p<n&&pp[p].x==pp[p+1].x) p++; for(j=i;j<=p;j++){ if(i==1){ dp[j]=1; a[j]=-1; } else{ k=lower_bound(b+1,b+1+m,pp[j].y)-b; if(k==1){ dp[j]=1; a[j]=-1; } else{ f=query(1,k-1); if(f==-1){ dp[j]=1; a[j]=-1; continue; } a[j]=f; dp[j]=dp[f]+1; } } } for(j=i;j<=p;j++){ k=lower_bound(b+1, b+1+m, pp[j].y)-b; merg(1,k,dp[j],j); } i=p; } p=0; for(i=1;i<=n;i++){ p=max(p,dp[i]); } for(i=1;i<=n;i++){ if(dp[i]==p){ printf("%d\n",p); printf("%d",pp[i].id); k=a[i]; while(k!=-1){ printf(" %d",pp[k].id); k=a[k]; } printf("\n"); break; } } }}
0 0
- Acdream 1126 Beautiful People(最长上升子序列,dp+线段树优化)
- ACdream 1216Beautiful People(二重最长上升子序列)
- ACdream 1216 Beautiful People 二路最长上升子序列
- ACdream 1216 Beautiful People 最长上升子序列变形
- ACdream 1216 Beautiful People(二路最长上升子序列 O(nlogn) )
- sgu199:Beautiful People(最长上升子序列)
- ACdream 1216 Beautiful People(二维上升子序列 O(nlogn))
- acdream 1426 Beautiful People(双线最长单调子序列)
- zoj 2391 Beautiful People 最长上升子序列
- 最长上升子序列nlogn通解(dp之线段树优化)
- code vs 2188 最长上升子序列(线段树优化DP)
- SGU 199. Beautiful People(最长上升子序列nlogn LIS)
- zoj 2319 Beautiful People 【最长上升序列】
- Beautiful People (最长单调递增子序列(变形))
- HDU 3308 最长上升连续子序列 (线段树)
- JZOJ 4920 降雷皇(最长上升子序列、线段树)
- 最长上升子序列 (dp)
- 最长公共上升子序列 (dp)
- 在android中创建bitmap避免内存不足的方法
- 存储圈装逼必上TOP 10网站
- java-正则表达式判断手机号
- hdu4429 Split the Rectangle(LCA)
- nginx学习十一 nginx启动流程
- Acdream 1126 Beautiful People(最长上升子序列,dp+线段树优化)
- iOS APP 上传
- 九月学习感想
- Win7下Qt532+MinGW482+OpenCV249+Cmake302编译环境搭建
- QuadCurveMenu菜单值得拥有
- Codeforces Round #271 (Div. 2) E Pillars(dp+线段树优化)
- 使用Junit对Java Web项目白盒测试
- 网络编程学习笔记(getservbyname和getservbyport函数)
- poj 3255 spfa(求次短路)