P1382 楼房 set用法小结
这个sb题目,剧毒。。。
STL大法好
首先,我准备用经典的线段树优化扫描线来做。之前的矩形周长把我困了数天导致我胸有成竹。
然后,敲代码半小时,调试半个月......这个,sb,怎么改都是0分+2个RE...
然后我爆炸了,请胡雨菲来帮忙。他还是提议我用set做。然后就set了...
跑的贼慢,不过90分,第八个点日常RE...
但是了解了一点set的用法,让我慢慢道来(嘿)
首先,可以看这个博客。
我自己的理解:
1,这是一种功能有限的搜索树。
2,它有序,资瓷插入删除,但是缓慢
3,这东西是返回指针的。
然后,反正这个set很naive就是了。
看下面一段代码:
#include <cstdio>
#include <set>
using namespace std;
set<int>s;
int main()
{
s.insert();
s.insert();
s.insert();
s.insert();
printf("%d\n",*s.end());
printf("%d\n",*s.rbegin());
return ;
}
set用法①
输出:
4
32
好,大致理解了吧。
#include <cstdio>
#include <set>
using namespace std;
set<int>s;
int main()
{
s.insert();
s.insert();
s.insert();
s.insert();
set<int>::iterator iter;
for(iter=s.begin();iter!=s.end();iter++) printf("%d ",*iter);
printf("\n");
s.erase();
for(iter=s.begin();iter!=s.end();iter++) printf("%d ",*iter);
s.erase(s.find());
printf("\n");
for(iter=s.begin();iter!=s.end();iter++) printf("%d ",*iter);
return ;
}
set用法②
输出:
15 22 24 32
15 22 32
15 32
这里说一下思路:我惯用的手法,重载运算符加优先队列存边。先出x小的,先出入边,入边先高,出边先低。然后如果某次出边后x和h都改变了就记录答案。
那么来看看我的90分代码。如果有机会A掉我再来改。
#include <cstdio>
#include <set>
#include <queue>
#include <algorithm>
using namespace std;
int x[],k;
int ans[][],ansk;
int cnt[];
struct Edge
{
int x,high,flag;
bool operator < (const Edge &a) const
{
if(this->x!=a.x) return this->x>a.x;
if(this->flag!=a.flag) return this->flag<a.flag;
if(a.flag==) return this->high<a.high;
return this->high>a.high;
}
};
priority_queue<Edge>p;
set<int>s;
void add_e(int high,int l,int r)
{
Edge ll,rr;
ll.flag=;
rr.flag=-;
ll.high=high;
rr.high=high;
ll.x=l;
rr.x=r;
p.push(ll);
p.push(rr);
return;
}
int main()
{
int n,xx,y,z;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&xx,&y,&z);
add_e(xx,y,z);
x[i]=xx;
}
sort(x+,x+n+);
for(int i=;i<=n;i++) if(x[i]!=x[i-]) x[++k]=x[i];
//for(int i=1;i<=k;i++) printf("%d ",x[i]);
//printf("\n");
Edge e;int lastx=-0x3f3f3f3f,lasth=;
s.insert();
while(!p.empty())
{
e=p.top();
p.pop();
int h=e.high;
//printf("h:%d\n",h);
h = upper_bound(x+,x++k,h) - x - ;
//printf("h:%d\n",h);
if(e.flag==)
{
if(!cnt[h]) s.insert(h);
cnt[h]++;
if( (*s.rbegin()!=lasth) && (e.x!=lastx) )
{
//printf("new ans!%d %d\n",e.x,x[*s.rbegin()]);
ans[++ansk][]=e.x;
ans[ansk][]=lasth;
ans[++ansk][]=e.x;
ans[ansk][]=*s.rbegin();
lasth=*s.rbegin();
lastx=e.x;
}
}
else
{
cnt[h]--;
if(!cnt[h]) s.erase(s.find(h));
if(*s.rbegin()!=lasth&&e.x!=lastx)
{
//printf("new ans!%d %d\n",e.x,x[*s.rbegin()]);
ans[++ansk][]=e.x;
ans[ansk][]=lasth;
ans[++ansk][]=e.x;
ans[ansk][]=*s.rbegin();
lasth=*s.rbegin();
lastx=e.x;
}
}
}
printf("%d\n",ansk);
for(int i=;i<=ansk;i++) printf("%d %d\n",ans[i][],x[ans[i][]]);
return ;
}
90分代码,跑的贼慢
还用到了离散化,具体看代码吧。
原来的naive爆0代码
#include <cstdio>
#include <queue>
#include <algorithm>
using namespace std;
int x[],k,ans[][],ansk;
struct Edge
{
int x,flag,high;
bool operator < (const Edge &a) const /// !!!!
{
if(this->x!=a.x)return this->x>a.x;
if(this->flag!=a.flag)return this->flag<a.flag;
if(this->flag==) return this->high<a.high;
return this->high>a.high;
}
};
priority_queue<Edge>p;
int c[],len[];
void add_e(int high,int l,int r)
{
Edge ll,rr;
ll.x=l;
rr.x=r;
ll.high=high;
rr.high=high;
ll.flag=;
rr.flag=-;
p.push(ll);
p.push(rr);
return;
} void update(int l,int r,int o)
{
if(c[o]>) /// !!!
{
if(l!=r)len[o]=x[r]-x[l];/// !
else if(l)len[o]=x[r]-x[l-];
else len[o]=x[r];
}
else if(l==r) len[o]=;
else len[o]=len[o<<]+len[o<<|];
return; } void add(int L,int R,int v,int l,int r,int o)
{
if(L<=l && r<=R)
{
c[o]+=v;
update(l,r,o);
return;
}
if(r<L || R<l) return;
int mid=(l+r)>>;
add(L,R,v,l,mid,o<<);
add(L,R,v,mid+,r,o<<|);
update(l,r,o);
return;
} int main()
{
int n,xx,y,z;
scanf("%d",&n);
for(int i=; i<=n; i++)
{
scanf("%d%d%d",&xx,&y,&z);
add_e(xx,y,z);
x[i]=xx;
}
sort(x+,x++n);
for(int i=; i<=n; i++)
{
if(x[i]!=x[i-]) x[++k]=x[i];
} ///离散化去重
Edge e;
int poi;
int lastx=-0x3f3f3f3f,lasth=; while(!p.empty())
{
e=p.top();
p.pop();
poi=upper_bound(x+,x+k+,e.high)-x-;
//printf("add:0 %d %d 0 %d 1\n",poi,e.flag,k);
add(,poi,e.flag,,k,);
//printf("len:%d\n",len[1]);
if(len[]!=lasth&&e.x!=lastx)
//if((e.x!=lastx||e.x==0) && len[1]!=lasth) ///!!!serious!
{
//printf("new ans!\n");
ans[++ansk][]=e.x;
ans[ansk][]=lasth;
ans[++ansk][]=e.x;
ans[ansk][]=len[];
lastx=e.x;
lasth=len[];
}
/**
if(e.flag==1) ///++
{
if(lasth==len[1]) continue;///高度没变,continue; }
else ///--
{ }
*/
}
printf("%d\n",ansk);
for(int i=; i<=ansk; i++) printf("%d %d\n",ans[i][],ans[i][]);
return ;
}
!!!!!!!!!!!!
再见。
不再见
A了,看看代码有什么变化?
#include <cstdio>
#include <set>
#include <queue>
#include <algorithm>
using namespace std;
long long int x[],k;
long long int ans[][],ansk;
long long int cnt[];
struct Edge
{
long long int x,high,flag;
bool operator < (const Edge &a) const
{
if(this->x!=a.x) return this->x>a.x;
if(this->flag!=a.flag) return this->flag<a.flag;
if(a.flag==) return this->high<a.high;
return this->high>a.high;
}
};
priority_queue<Edge>p;
set<long long int>s;
void add_e(long long int high,long long int l,long long int r)
{
Edge ll,rr;
ll.flag=;
rr.flag=-;
ll.high=high;
rr.high=high;
ll.x=l;
rr.x=r;
p.push(ll);
p.push(rr);
return;
}
int main()
{
long long int n,xx,y,z;
scanf("%lld",&n);
for(int i=;i<=n;i++)
{
scanf("%lld%lld%lld",&xx,&y,&z);
add_e(xx,y,z);
x[i]=xx;
}
sort(x+,x+n+);
for(int i=;i<=n;i++) if(x[i]!=x[i-]) x[++k]=x[i];
//for(int i=1;i<=k;i++) printf("%d ",x[i]);
//printf("\n");
Edge e;long long int lastx=-0x3f3f3f3f,lasth=;
s.insert();
while(!p.empty())
{
e=p.top();
p.pop();
long long int h=e.high;
//printf("h:%d\n",h);
h = upper_bound(x+,x++k,h) - x - ;
//printf("h:%d\n",h);
if(e.flag==)
{
if(!cnt[h]) s.insert(h);
cnt[h]++;
if( (*s.rbegin()!=lasth) && (e.x!=lastx) )
{
//printf("new ans!%d %d\n",e.x,x[*s.rbegin()]);
ans[++ansk][]=e.x;
ans[ansk][]=lasth;
ans[++ansk][]=e.x;
ans[ansk][]=*s.rbegin();
lasth=*s.rbegin();
lastx=e.x;
}
}
else
{
cnt[h]--;
if(!cnt[h]) s.erase(s.find(h));
if(*s.rbegin()!=lasth&&e.x!=lastx)
{
//printf("new ans!%d %d\n",e.x,x[*s.rbegin()]);
ans[++ansk][]=e.x;
ans[ansk][]=lasth;
ans[++ansk][]=e.x;
ans[ansk][]=*s.rbegin();
lasth=*s.rbegin();
lastx=e.x;
}
}
}
printf("%lld\n",ansk);
for(int i=;i<=ansk;i++) printf("%lld %lld\n",ans[i][],x[ans[i][]]);
return ;
}
就是她
数组开大⑩倍+全体换成long long
就A了......
P1382 楼房 set用法小结的更多相关文章
- 转载:Hadoop排序工具用法小结
本文转载自Silhouette的文章,原文地址:http://www.dreamingfish123.info/?p=1102 Hadoop排序工具用法小结 发表于 2014 年 8 月 25 日 由 ...
- [No000010]Ruby 中一些百分号(%)的用法小结
#Ruby 中一些百分号(%)的用法小结 #这篇文章主要介绍了Ruby 中一些百分号(%)的用法小结,需要的朋友可以参考下 what_frank_said = "Hello!"#% ...
- C++ typedef用法小结 (※不能不看※)
C++ typedef用法小结 (※不能不看※) 第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // 这多数不 ...
- 函数fgets和fputs、fread和fwrite、fscanf和fprintf用法小结 (转)
函数fgets和fputs.fread和fwrite.fscanf和fprintf用法小结 字符串读写函数fgets和fputs 一.读字符串函数fgets函数的功能是从指定的文件中读一个字符串到字符 ...
- 1:CSS中一些@规则的用法小结 2: @media用法详解
第一篇文章:@用法小结 第二篇文章:@media用法 第一篇文章:@用法小结 这篇文章主要介绍了CSS中一些@规则的用法小结,是CSS入门学习中的基础知识,需要的朋友可以参考下 at-rule ...
- 英语语法最终珍藏版笔记- 21it 用法小结
it 用法小结 it 在英语中的意思较多,用法较广,现总结如下. 一.it作句子的真正主语 1.it 指前面已经提到过的人或事物,有时指心目中的或成为问题的人或事物,作真正主语. 例如: What’s ...
- [转]ssh常用用法小结
ssh常用用法小结 1.连接到远程主机: 命令格式 : ssh name@remoteserver 或者 ssh remoteserver -l name 说明:以上两种方式都可以远程登录到远程主机, ...
- 结构体定义 typedef struct 用法详解和用法小结
typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便.具体区别在于:若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,stru ...
- typedef用法小结
typedef用法小结- - 注意:本文转自网络,版权归原作者所有. typedef typedef用法小结- - 这两天在看程序的时候,发现很多地方都用到typedef,在结构体定义,还有一些数组等 ...
随机推荐
- NuGet 使用笔记
环境准备 1. 下载nuget : https://www.nuget.org/downloads 2. 设置到环境变量Path, 使生效:在Cmd打入: set path=abc 关闭Cmd (C ...
- GlusterFS分布式存储学习笔记
分布式文件系统 分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源并不直接与本地节点相连,而是分布于计算网络中的一个或者多个节点的计算机上.目前意义上的分布 ...
- nginx通过https方式反向代理多实例tomcat
案例说明:前面一层nginx+Keepalived部署的LB,后端两台web服务器部署了多实例的tomcat,通过https方式部署nginx反向代理tomcat请求.配置一如下: 1)LB层的ngi ...
- MongoDB副本集(一主一备+仲裁)环境部署-运维操作记录
MongoDB复制集是一个带有故障转移的主从集群.是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复.MongoDB复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举产生一 ...
- SCRUM 12.18
明天就是编译课设的第二次中期考核了,大家都感到有一些压力. 所以我们决定今天减少一些工作量. 工作任务分配依旧如往常 成员 任务 彭林江 落实API 郝倩 研究遍历美团数据方法 牛强 落实意见反馈功能 ...
- linux第四次读书笔记
第四章:进程调度 一.多任务 1.非抢占式多任务 进程会一直执行直到自己主动停止运行(这一步骤称为让步) 2.抢占式多任务 Linux/Unix使用的是抢占式的方式:强制的挂起进程的动作就叫做抢占.进 ...
- 结对项目gobang
题目介绍:实现五子棋的基本规则,分黑棋和白棋.连成5个的胜利,完成了五子棋的单人游戏. 代码地址:https://github.com/liuxianchen/gobang 结对人:刘仙臣 康佳 结 ...
- SpringMVC视图解析器概述
不论控制器返回一个String,ModelAndView,View都会转换为ModelAndView对象,由视图解析器解析视图,然后,进行页面的跳转. 控制器处理方法---->ModelAndV ...
- activiti-ldap-integration
https://stackoverflow.com/questions/19488764/activiti-ldap-integration https://community.alfresco.co ...
- Ubuntu设置静态IP的方法
通过修改配置文件/etc/network/interfaces,如果/etc/resolv.conf中提示nameserver会被resolvconf修改,是临时文件,那么dns server也可以在 ...