7.20套娃(tao)

套娃(tao)

input
7 3
9 5
3 7
10 6
5 10
2 6
10 10
4 1
10 5
3 5
3 9
output
0
1
2

sol:

把查询想象成(x1,y1)向(x2,y2)有边当且仅当(x1<x2,y1<y2)

有个性质就是:这张图的最小链覆盖=最长反链

反链就是满足(x1<x2,y1>y2) ,所以把点按照x排序后就是求最长下降子序列

然后扫描线扫过去,用树状数组维护一下最长下降子序列即可

#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
    ll s=0; bool f=0; char ch=' ';
    while(!isdigit(ch)) {f|=(ch=='-'); ch=getchar();}
    while(isdigit(ch)) {s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
    if(x<0) {putchar('-'); x=-x;}
    if(x<10) {putchar(x+'0'); return;}
    write(x/10); putchar((x%10)+'0');
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=200005;
int n,Q,c[N],ans[N];
struct Node
{
    int r,h,id;
    inline bool operator<(const Node &tmp)const
    {
        return r>tmp.r||(r==tmp.r&&h<tmp.h)||(r==tmp.r&&h==tmp.h&&id<tmp.id);
    }
}a[N<<1];
struct BIT
{
    int S[N];
    #define lowbit(x) ((x)&(-x))
    inline void add(int x,int y)
    {
        for(;x<=n;x+=lowbit(x)) S[x]=max(S[x],y);
    }
    inline int Que(int x)
    {
        int ans=0;
        for(;x;x-=lowbit(x)) ans=max(ans,S[x]);
        return ans;
    }
}T;
int main()
{
    freopen("tao.in","r",stdin);
    freopen("tao.out","w",stdout);
    int i;
    R(n); R(Q);
    for(i=1;i<=n;i++)
    {
        R(a[i].r); R(a[i].h); a[i].id=0; c[i]=a[i].h;
    }
    for(i=1;i<=Q;i++)
    {
        R(a[n+i].r); R(a[n+i].h); a[n+i].id=i;
    }
    sort(c+1,c+n+1); *c=unique(c+1,c+n+1)-c-1;
    sort(a+1,a+n+Q+1);
    for(i=1;i<=n+Q;i++)
    {
        a[i].h=upper_bound(c+1,c+*c+1,a[i].h)-c-1;
        if(a[i].id) ans[a[i].id]=T.Que(a[i].h);
        else T.add(a[i].h,T.Que(a[i].h)+1);
    }
    for(i=1;i<=Q;i++) Wl(ans[i]);
    return 0;
}
/*
input
7 3
9 5
3 7
10 6
5 10
2 6
10 10
4 1
10 5
3 5
3 9
output
0
1
2
*/
View Code

猜你喜欢

转载自www.cnblogs.com/gaojunonly1/p/11223757.html