您的位置:首页 > 其它

Man Down HDU - 3016

2018-02-14 18:15 344 查看
点击打开链接题目和 poj1661 几乎一样 只是数据量加大
每个线段的左右端点找需要落脚点 在poj1661中完全可以依次枚举 但这个过程可以用线段树优化 对于一个端点只需看下面包含它的最高的线段是谁 即区间染色与单点查询

#include <bits/stdc++.h>
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
.h=0,line
.l=1,line
.r=100000,line
.val=0;
line
.pl=-1,line
.pr=-1,line
.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
.maxx=line
.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: