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,在结构体定义,还有一些数组等 ...
随机推荐
- [朴智妍][Lullaby]
歌词来源:http://music.163.com/#/song?id=484056971 作曲 : Bum/Sophiya/김용신 [作曲 : Bum/Sophiya/k/gi-myong-xin] ...
- nginx反向代理中proxy_set_header 运维笔记
Nginx proxy_set_header:即允许重新定义或添加字段传递给代理服务器的请求头.该值可以包含文本.变量和它们的组合.在没有定义proxy_set_header时会继承之前定义的值.默认 ...
- B. Divisor Subtraction
链接 [http://codeforces.com/contest/1076/problem/B] 题意 给你一个小于1e10的n,进行下面的运算,n==0 结束,否则n-最小质因子,问你进行多少步 ...
- DWR实现服务器向客户端推送消息
原文链接 http://www.blogjava.net/stevenjohn/archive/2012/07/07/382447.html这片文章还是给了我很大帮助,再次表示感谢,下面我将这两天的研 ...
- 第一次Sprint
项目刚开始做的话,离客户的需求应该,蛮远的. 用的是eclipse加安卓模拟器在弄. 目前主要弄APP的界面和一些主要的功能算法,各个功能板块的位置划分的内容. Github团队地址是:https:/ ...
- java collections - keyset() vs entrySet() in map
https://stackoverflow.com/questions/8962459/java-collections-keyset-vs-entryset-in-map http://blog.c ...
- php函数值传值/地址以及引用的用法
博客摘自 奔跑的大白,网址: http://www.cnblogs.com/gauze/p/5568867.html 1.先来解释一下名词. 值传递(passl-by-value)过程中,被调函数的 ...
- Node 开启
cmd //进入命令行 D: //指定磁盘 cd 文件路径 //指定路径 node 文件名.js //执行文件 增补: Node执行js文件自动嵌套 (functio ...
- 软件工程_9th weeks
PSP DATE START_TIME END_TIME EVENT TYPE TIME 4.30-5.3 5:30 4:00 旅游 娱乐 72h 5.3 14:00 17:0 ...
- Django admin 一些有用的设置
Django自带的后台管理是Django明显特色之一,可以让我们快速便捷管理数据.后台管理可以在各个app的admin.py文件中进行控制.以下是我最近摸索总结出比较实用的配置.若你有什么比较好的 ...