zoukankan      html  css  js  c++  java
  • 【SPOJ2371】LIS2

    题目大意:求二维最长上升子序列的长度。

    题解:
    可以看出,这个问题等价于三维偏序问题。
    不过在进行分治的时候要注意,由于 dp 转移是有顺序的,因此只能先处理左半部分,再处理左半部分对右边的贡献,最后处理右半部分。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    
    int n,ans,d[maxn],tot,dp[maxn];
    struct node{int x,y,id;}p[maxn],tmp[maxn];
    int bit[maxn];
    void modify(int pos,int val){
    	for(int i=pos;i<=tot;i+=i&-i)bit[i]=max(bit[i],val);
    }
    int query(int pos){
    	int ret=0;
    	for(int i=pos;i;i-=i&-i)ret=max(ret,bit[i]);
    	return ret;
    }
    void clear(int pos){
    	for(int i=pos;i<=tot;i+=i&-i)bit[i]=0;
    }
    
    void cdq(int l,int r){
    	if(l==r)return;
    	int mid=l+r>>1;
    	cdq(l,mid);
    	sort(p+l,p+mid+1,[](const node &a,const node &b){return a.x<b.x;});
    	sort(p+mid+1,p+r+1,[](const node &a,const node &b){return a.x<b.x;});
    	for(int x=l,y=mid+1;y<=r;y++){
    		while(x<=mid&&p[x].x<p[y].x)modify(p[x].y,dp[p[x].id]),++x;
    		dp[p[y].id]=max(dp[p[y].id],query(p[y].y-1)+1);
    	}
    	for(int i=l;i<=mid;i++)clear(p[i].y);
    	sort(p+mid+1,p+r+1,[](const node &a,const node &b){return a.id<b.id;});
    	cdq(mid+1,r);
    }
    void read_and_parse(){
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%d%d",&p[i].x,&p[i].y);
    		p[i].id=i,d[++tot]=p[i].y;
    	}
    	sort(d+1,d+tot+1);
    	tot=unique(d+1,d+tot+1)-d-1;
    	for(int i=1;i<=n;i++)p[i].y=lower_bound(d+1,d+tot+1,p[i].y)-d;
    }
    void solve(){
    	for(int i=1;i<=n;i++)dp[i]=1;
    	cdq(1,n);
    	for(int i=1;i<=n;i++)ans=max(ans,dp[i]);
    	printf("%d
    ",ans);
    }
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    1.saltstack入门
    构造函数
    gitlab
    mysql常见的问题
    python数据运算
    BZOJ 1691 usaco2007 挑剔的美食家
    BZOJ 1708 usaco2007 Money奶牛的硬币
    BZOJ 1050 HAOI2006 旅行comf
    BZOJ 2427 HAOI2010 软件安装
    BZOJ 1901 Dynamic Rankings
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/11110182.html
Copyright © 2011-2022 走看看