点击打开链接
题目和 poj1661 几乎一样 只是数据量加大
每个线段的左右端点找需要落脚点 在poj1661中完全可以依次枚举 但这个过程可以用线段树优化 对于一个端点只需看下面包含它的最高的线段是谁 即区间染色与单点查询
using namespace std;
struct node1
{
    int h;
    int l;
    int r;
    int val;
    int pl;
    int pr;
    int maxx;
};
struct node2
{
    int l;
    int r;
    int laz;
    int val;
};
node1 line[100010];
node2 tree[400010];
int n;
bool cmp(node1 n1,node1 n2)
{
    return n1.h<n2.h;
}
void pushdown(int cur)
{
    if(tree[cur].laz)
    {
        tree[cur*2].laz=tree[cur*2+1].laz=tree[cur].laz;
        tree[cur*2].val=tree[cur*2+1].val=tree[cur].laz;
        tree[cur].laz=0;
    }
    return;
}
void build(int l,int r,int cur)
{
    int m;
    tree[cur].l=l;
    tree[cur].r=r;
    tree[cur].laz=0;
    tree[cur].val=1;
    if(l==r) return;
    m=(l+r)/2;
    build(l,m,cur*2);
    build(m+1,r,cur*2+1);
    return;
}
int query(int tar,int cur)
{
    if(tree[cur].l==tree[cur].r)
    {
        return tree[cur].val;
    }
    pushdown(cur);
    if(tar<=tree[cur*2].r) return query(tar,cur*2);
    else return query(tar,cur*2+1);
}
void update(int ll,int rr,int val,int cur)
{
    if(ll<=tree[cur].l&&tree[cur].r<=rr)
    {
        tree[cur].laz=val;
        tree[cur].val=val;
        return;
    }
    pushdown(cur);
    if(ll<=tree[cur*2].r) update(ll,rr,val,cur*2);
    if(rr>=tree[cur*2+1].l) update(ll,rr,val,cur*2+1);
    return;
}
int main()
{
    int i;
    while(scanf("%d",&n)!=EOF)
    {
        build(1,100000,1);
        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d%d",&line[i].h,&line[i].l,&line[i].r,&line[i].val);
            line[i].pl=-1,line[i].pr=-1,line[i].maxx=0;
        }
        n++;
        line[n].h=0,line[n].l=1,line[n].r=100000,line[n].val=0;
        line[n].pl=-1,line[n].pr=-1,line[n].maxx=0;
        sort(line+1,line+n+1,cmp);
        for(i=2;i<=n;i++)
        {
            line[i].pl=query(line[i].l,1);
            line[i].pr=query(line[i].r,1);
            update(line[i].l,line[i].r,i,1);
        }
        line[n].maxx=line[n].val+100;
        for(i=n;i>=2;i--)
        {
            line[line[i].pl].maxx=max(line[line[i].pl].maxx,line[i].maxx+line[line[i].pl].val);
            line[line[i].pr].maxx=max(line[line[i].pr].maxx,line[i].maxx+line[line[i].pr].val);
        }
        if(line[1].maxx==0)
        {
            printf("-1\n");
        }
        else
        {
            printf("%d\n",line[1].maxx);
        }
    }
    return 0;
}
                










