您的位置:首页 > 其它

hdu 5324 Boring Class(15多校第三场1009)(cdq分治)

2015-07-30 08:51 267 查看
//cdq分治
//用cdq分治变无序为有序,降低时间复杂度。
//降二维为一维。好神奇,虽然还是不大明白。orz
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
#define eps 1e-9
#define inf 1e9
const int N=120010;
int c
;
struct query{
int x,y,id;
}q
,p
;
bool cmp(query a,query b){
if(a.y!=b.y)return a.y<b.y;//y从小到大
return a.x>b.x;
}
int tot;
void input(int n){//输入加离散化
tot=0;
for(int i=1;i<=n;i++){
scanf("%d",&q[i].x);
c[tot++]=q[i].x;
q[i].id=i;
}
for(int i=1;i<=n;i++){
scanf("%d",&q[i].y);
c[tot++]=q[i].y;
}
sort(c,c+tot);
tot=unique(c,c+tot)-c;
for(int i=1;i<=n;i++){
q[i].x=lower_bound(c,c+tot,q[i].x)-c+1;
q[i].y=lower_bound(c,c+tot,q[i].y)-c+1;
}
}
int dp
;
int bit
;
int lowbit(int x){
return x&(-x);
}
void update(int pos,int val){
int x=pos;
while(x<tot+10){
bit[x]=max(bit[x],val);
x+=lowbit(x);
}
}
int getsum(int pos){
int x=pos;
int ans=0;
while(x>0){
ans=max(ans,bit[x]);
x-=lowbit(x);
}
return ans;
}
void clear(int i)
{
for(;i<tot+10;i+=lowbit(i))
bit[i]=0;
}
void solve(int l,int r){
if(l==r){
dp[l]=max(dp[l],1);
return;
}
int mid=(l+r)>>1;
solve(mid+1,r);
for(int i=l;i<=r;i++){
p[i]=q[i];
}
sort(p+l, p+mid+1,cmp);
sort(p+mid+1,p+r+1,cmp);
for(int i=mid,j=r;i>=l;i--){//从大-->小 ,前面的一定大于后面的
while(j>mid&&p[i].y<=p[j].y){
update(p[j].x,dp[p[j].id]);//更新树状数组
j--;
}
dp[p[i].id]=max(dp[p[i].id],getsum(p[i].x)+1);
}
for(int i=mid+1;i<=r;i++)
clear(p[i].x);
solve(l,mid);
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
memset(q, 0, sizeof(q));
memset(p, 0, sizeof(p));
input(n);
memset(dp, 0, sizeof(dp));
solve(1,n);
int ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
int pre=0;
for(int i=1;i<=n;i++){
if(dp[i]==ans&&(pre==0||(q[pre].x>=q[i].x&&q[pre].y<=q[i].y))){
ans--;pre=i;
printf("%d",i);
if(ans)printf(" ");
else printf("\n");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: