「JOISC 2016 Day 1」俄罗斯套娃(二维偏序)
作者:互联网
「JOISC 2016 Day 1」俄罗斯套娃
思路清奇的呀,先在坐标轴上画图(R为横坐标,H为纵坐标),然后发现每个询问之间没有影响,考虑离线处理,因为询问的要求是选择>=R的,所以把横坐标从大到小排序,二维偏序?,那么在H对应的纵坐标上画一条线,就发现是在这以下的娃娃都满足,然后就树状数组维护不可以套起来的,可以画图理解,就是一个娃娃右上方的,答案是所有不能连接的形成的链的最大值,注意一下更新方式,因为最外面的娃娃也算没有套的,所以就是最大值(真一开始没想通)
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y,id;/*直径,高度*/
}a[400010];
int cmp(node x,node y){
if(x.x!=y.x)return x.x>y.x;
if(x.y!=y.y)return x.y<y.y;
return x.id<y.id;
}
int tree[400010],l[800010];
int find(int x,int le,int ri){
int ans=0;
while(le<=ri){
int mid=le+ri>>1;
if(l[mid]<=x)ans=mid,le=mid+1;
else ri=mid-1;
}
return ans;
}
int ans[200010],nn;
void add(int x,int val){
for(;x<=nn;x+=x&-x)tree[x]=max(tree[x],val);
}
int qu(int x){
int ans=0;
for(;x;x-=x&-x)ans=max(ans,tree[x]);
return ans;
}
int main(){
int n,q;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y),a[i].id=0,l[i*2-1]=a[i].x,l[i*2]=a[i].y;
for(int i=1;i<=q;i++)scanf("%d%d",&a[i+n].x,&a[i+n].y),a[i+n].id=i,l[(i+n)*2-1]=a[i].x,l[(i+n)*2]=a[i].y;
sort(l+1,l+(q+n)*2+1);
for(int i=1;i<=(n+q)*2;i++)if(l[i]!=l[i-1])l[++nn]=l[i];
sort(a+1,a+1+n+q,cmp);//R从大到小
for(int i=1;i<=q+n;i++){
int r=find(a[i].x,1,nn),h=find(a[i].y,1,nn);
if(!a[i].id)add(h,qu(h)+1/*注意不是加一*/);
else ans[a[i].id]=qu(h);
}
for(int i=1;i<=q;i++)printf("%d\n",ans[i]);
return 0;
}
标签:偏序,node,套娃,JOISC,return,2016,Day 来源: https://www.cnblogs.com/lefy959/p/16632636.html