您的位置:首页 > 其它

AC日记——楼房 codevs 2995

2017-01-05 22:00 281 查看

2995 楼房

时间限制: 1 s

空间限制: 256000 KB

题目等级 : 黄金 Gold

题解
查看运行结果

题目描述 Description

地平线(x轴)上有n个矩(lou)形(fang),用三个整数h[i],l[i],r[i]来表示第i个矩形:矩形左下角为(l[i],0),右上角为(r[i],h[i])。地平线高度为0。在轮廓线长度最小的前提下,从左到右输出轮廓线。

#include <map>
#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

struct node {
int l,r,dis;
};
struct node edge[100001];

inline void read_int(int &now_);

class T_tree {
public:
int l,r,mid,dis,flag;

void mid_()
{
mid=(l+r)>>1;
}

void flag_()
{
flag=0;
}

void dis_()
{
//read_int(dis);
dis=0;
}
};
class T_tree tree[100001*4*2];
class T_tree ok[100001*4*2];

int n,if_Z,num=0,before=0,before_=0;
int point[100001*2],ans=0,ans_now[100001*2+1000],ans_dis[100001*2+1000];

char Cget;

bool if_fi=true;

map<int,int>if_;

inline void read_int(int &now_)
{
now_=0,if_Z=1,Cget=getchar();
while(Cget<'0'||Cget>'9')
{
if(Cget=='-') if_Z=-1;
Cget=getchar();
}
while(Cget<='9'&&Cget>='0')
{
now_=now_*10+Cget-'0';
Cget=getchar();
}
now_*=if_Z;
}

inline bool cmp(struct node some1,struct node some2)
{
return some1.dis<some2.dis;
}

void ok_build(int now,int l,int r)
{
ok[now].l=l,ok[now].r=r;
if(l==r) return ;
ok[now].mid_();
ok_build(now<<1,l,ok[now].mid);
ok_build(now<<1|1,ok[now].mid+1,r);
}

void ok_down(int now)
{
if(ok[now].l==ok[now].r) return ;
ok[now<<1].dis=ok[now].flag;
ok[now<<1].flag=ok[now].flag;
ok[now<<1|1].dis=ok[now].flag;
ok[now<<1|1].flag=ok[now].flag;
ok[now].flag=0;
}

void ok_change(int now,int l,int r)
{
if(ok[now].dis) return ;
if(ok[now].l==ok[now].r)
{
ok[now].dis=1;
ok[now].flag=1;
ok_down(now);
return ;
}
if(ok[now].flag) ok_down(now);
if(l>ok[now].mid) ok_change(now<<1|1,l,r);
else if(r<=ok[now].mid) ok_change(now<<1,l,r);
else
{
ok_change(now<<1,l,ok[now].mid);
ok_change(now<<1|1,ok[now].mid+1,r);
}
}

bool ok_ko(int now,int to)
{
if(ok[now].dis) return true;
if(ok[now].l==ok[now].r&&ok[now].l==to)
{
return false;
}
if(ok[now].flag) ok_down(now);
if(ok[now].l>to) return ok_ko(now<<1|1,to);
else return ok_ko(now<<1,to);
}

void tree_build(int now,int l,int r)
{
tree[now].l=l,tree[now].r=r;
if(l==r)
{
tree[now].dis_();
return ;
}
tree[now].mid_();
tree_build(now<<1,l,tree[now].mid);
tree_build(now<<1|1,tree[now].mid+1,r);
}

inline void tree_down(int now)
{
if(tree[now].l==tree[now].r) return ;
tree[now<<1].dis=tree[now].flag;
tree[now<<1].flag=tree[now].flag;
tree[now<<1|1].dis=tree[now].flag;
tree[now<<1|1].flag=tree[now].flag;
tree[now].flag_();
}

void tree_change(int now,int l,int r,int dis)
{
if(tree[now].l==l&&tree[now].r==r)
{
tree[now].dis=dis;
tree[now].flag=dis;
tree_down(now);
return ;
}
if(tree[now].flag) tree_down(now);
if(l>tree[now].mid) tree_change(now<<1|1,l,r,dis);
else if(r<=tree[now].mid) tree_change(now<<1,l,r,dis);
else
{
tree_change(now<<1,l,tree[now].mid,dis);
tree_change(now<<1|1,tree[now].mid+1,r,dis);
}
}

int times=0;

void tree_check(int now)
{
if(tree[now].l==tree[now].r)
{
/*if(tree[now].dis!=before_)
{
times++;
if(times==1)
{
printf("%d %d\n",point[tree[now].l],before);
printf("%d %d\n",point[tree[now].l],tree[now].dis);
}
else
{
printf("%d %d\n",point[tree[now].l],tree[now].dis);
}
before_=tree[now].dis;
}*/
//printf("(%d,%d)",point[tree[now].l],tree[now].dis);
if(tree[now].l==num+1)
{
if(before!=0)
{
//printf("%d %d\n",point[num],before);
//printf("%d %d\n",point[num],0);
ans_now[++ans]=point[num];
ans_dis[ans]=before;
ans_now[++ans]=point[num];
ans_dis[ans]=0;
}
}
else
{
if(ok_ko(1,tree[now].l-1))
{
if(tree[now].dis!=before)
{
//printf("%d %d\n%d %d\n",point[tree[now].l],before,point[tree[now].l],tree[now].dis);
ans_now[++ans]=point[tree[now].l];
ans_dis[ans]=before;
ans_now[++ans]=point[tree[now].l];
ans_dis[ans]=tree[now].dis;
before=tree[now].dis;
}
}
else
{
if(before!=0)
{
//printf("%d %d\n",point[tree[now].l-1],point[tree[now].l]);
ans_now[++ans]=point[tree[now].l-1];
ans_dis[ans]=before;
ans_now[++ans]=point[tree[now].l-1];
ans_dis[ans]=0;
ans_now[++ans]=point[tree[now].l];
ans_dis[ans]=0;
ans_now[++ans]=point[tree[now].l];
ans_dis[ans]=tree[now].dis;
before=tree[now].dis;
}
}
}
//printf("(%d %d)\n",point[tree[now].l],tree[now].dis);
return ;
}
if(tree[now].flag) tree_down(now);
tree_check(now<<1),tree_check(now<<1|1);
}

int main()
{
read_int(n);
for(int i=1;i<=n;i++)
{
read_int(edge[i].dis),read_int(edge[i].l),read_int(edge[i].r);
if_[edge[i].l]=edge[i].l,if_[edge[i].r]=edge[i].r;
}
//  printf("\n\n");
for(map<int,int>::iterator it=if_.begin();it!=if_.end();it++)
{
point[++num]=it->first;
it->second=num;
//    printf("%d %d\n",num,point[num]);
}
tree_build(1,1,num+1);
ok_build(1,0,num-1);
ok_change(1,0,0);
sort(edge+1,edge+n+1,cmp);
for(int i=1;i<=n;i++)
{
printf("%d %d\n",if_[edge[i].l],if_[edge[i].r]);
}
printf("\n\n");
for(int i=1;i<=n;i++)
{
//printf("%d %d %d\n\n",if_[edge[i].l],if_[edge[i].r],edge[i].dis);
tree_change(1,if_[edge[i].l],if_[edge[i].r],edge[i].dis);
ok_change(1,if_[edge[i].l],if_[edge[i].r]-1);
printf("%d %d\n",if_[edge[i].l],if_[edge[i].r]-1);
//ans=0;
//before=0;
//tree_check(1);
//printf("\n");
//printf("%d %d %d\n",if_[edge[i].l],if_[edge[i].r],edge[i].dis);
}
printf("\n\n");
//ans=0;
//before=0;
tree_check(1);
//printf("\n\n");
printf("%d\n",ans);
for(int i=1;i<=ans;i++) printf("%d %d\n",ans_now[i],ans_dis[i]);
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: