【线段树】【扫描线】Petrozavodsk Winter Training Camp 2018 Day 5: Grand Prix of Korea, Sunday, February 4, 2018 Problem A. Donut
题意:平面上n个点,每个点带有一个或正或负的权值,让你在平面上放一个内边长为2l,外边长为2r的正方形框,问你最大能圈出来的权值和是多少?
容易推出,能框到每个点的 框中心 的范围也是一个以该点为中心的相同大小的框。
于是,把每个点的框拆成4条线。从下往上扫过去,最下面的线,给[R,R]区间加上该点的权值,然后上面再给[L,L]减去,然后上面再给[L,L]加上,然后再往上在给[R,R]减去即可。每次扫完一行,就用线段树的全局最大值尝试更新答案。
两个坑点:首先,由于线段树里存储的是离散后的点,所以有可能会存在一些死角,所以给离散化后的每两个点之间再插入一个点,这样不会有死角。
其次,出边对应的线要向上移动一个单位,并且左右端点向内缩小一个单位,这样方便处理。
(UPDATE:虽然AC了此题,但是被HACK了,怀疑是“出边对应的线要向上移动一个单位,并且左右端点向内缩小一个单位”这里有BUG)
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
struct data{
int p;
ll v;
}t[1200005];
int a[1200005];
bool cmp(const data &a,const data &b){
return a.v<b.v;
}
struct LINE{
int y;
int l,r;
int w;
bool in;
}lines[400005];
bool cm2(const LINE &a,const LINE &b){
return a.y!=b.y ? a.y<b.y : a.in>b.in;
}
int n,L,R,e,zy;
int y[100005],z[100005],ans;
int maxv[4800005],delta[4800005];
void pushdown(int rt){
if(delta[rt]){
delta[rt<<1]+=delta[rt];
delta[rt<<1|1]+=delta[rt];
maxv[rt<<1]+=delta[rt];
maxv[rt<<1|1]+=delta[rt];
delta[rt]=0;
}
}
void update(int ql,int qr,int v,int rt,int l,int r){
if(ql<=l && r<=qr){
maxv[rt]+=v;
delta[rt]+=v;
return;
}
int m=(l+r>>1);
pushdown(rt);
if(ql<=m){
update(ql,qr,v,rt<<1,l,m);
}
if(m<qr){
update(ql,qr,v,rt<<1|1,m+1,r);
}
maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
}
int main(){
// freopen("a.in","r",stdin);
int x;
scanf("%d%d%d",&n,&L,&R);
for(int i=1;i<=n;++i){
scanf("%d%d%d",&x,&y[i],&z[i]);
t[++e].v=(ll)(x-R)*2ll;
t[e].p=e;
t[++e].v=(ll)(x-R)*2ll-1ll;
t[e].p=e;
t[++e].v=(ll)(x-R)*2ll+1ll;
t[e].p=e; t[++e].v=(ll)(x-L+1)*2ll;
t[e].p=e;
t[++e].v=(ll)(x-L+1)*2ll-1ll;
t[e].p=e;
t[++e].v=(ll)(x-L+1)*2ll+1ll;
t[e].p=e; t[++e].v=(ll)(x+L-1)*2ll;
t[e].p=e;
t[++e].v=(ll)(x+L-1)*2ll-1ll;
t[e].p=e;
t[++e].v=(ll)(x+L-1)*2ll+1ll;
t[e].p=e; t[++e].v=(ll)(x+R)*2;
t[e].p=e;
t[++e].v=(ll)(x+R)*2-1;
t[e].p=e;
t[++e].v=(ll)(x+R)*2+1;
t[e].p=e;
}
sort(t+1,t+e+1,cmp);
a[t[1].p]=++zy;
for(int i=2;i<=e;++i){
if(t[i].v!=t[i-1].v){
++zy;
}
a[t[i].p]=zy;
}
for(int i=1;i<=n;++i){
lines[i*4-3].y=y[i]-R;
lines[i*4-2].y=y[i]-L+1;
lines[i*4-1].y=y[i]+L;
lines[i*4-0].y=y[i]+R+1; lines[i*4-3].l=a[i*12-11];
lines[i*4-2].l=a[i*12-8];
lines[i*4-1].l=a[i*12-8];
lines[i*4-0].l=a[i*12-11]; lines[i*4-3].r=a[i*12-2];
lines[i*4-2].r=a[i*12-5];
lines[i*4-1].r=a[i*12-5];
lines[i*4-0].r=a[i*12-2]; lines[i*4-3].w=z[i];
lines[i*4-2].w=z[i];
lines[i*4-1].w=z[i];
lines[i*4-0].w=z[i]; lines[i*4-3].in=1;
lines[i*4-2].in=0;
lines[i*4-1].in=1;
lines[i*4-0].in=0;
}
sort(lines+1,lines+(n<<2|1),cm2);
for(int i=1;i<=(n<<2);++i){
if(lines[i].in){
update(lines[i].l,lines[i].r,lines[i].w,1,1,zy);
}
else{
update(lines[i].l,lines[i].r,-lines[i].w,1,1,zy);
}
if(lines[i].y!=lines[i+1].y){
ans=max(ans,maxv[1]);
}
}
printf("%d\n",ans);
return 0;
}
【线段树】【扫描线】Petrozavodsk Winter Training Camp 2018 Day 5: Grand Prix of Korea, Sunday, February 4, 2018 Problem A. Donut的更多相关文章
- 【推导】【数学期望】【冒泡排序】Petrozavodsk Winter Training Camp 2018 Day 5: Grand Prix of Korea, Sunday, February 4, 2018 Problem C. Earthquake
题意:两地之间有n条不相交路径,第i条路径由a[i]座桥组成,每座桥有一个损坏概率,让你确定一个对所有桥的检测顺序,使得检测所需的总期望次数最小. 首先,显然检测的时候,是一条路径一条路径地检测,跳跃 ...
- 【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans
一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函 ...
- 【线段树】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem H. Hay
有一些草,一开始高度都是0,它们的生长速率不同. 给你一些单增的日期,在这些日期要将>b的草的部分都割掉,问你每次割掉的部分有多少. 将草的生长速率从大到小排序,这样每次割掉的是一个后缀,而且不 ...
- Petrozavodsk Winter Training Camp 2018
Petrozavodsk Winter Training Camp 2018 Problem A. Mines 题目描述:有\(n\)个炸弹放在\(x\)轴上,第\(i\)个位置为\(p_i\),爆炸 ...
- 2015-2016 Petrozavodsk Winter Training Camp, Nizhny Novgorod SU Contest (5/9)
2015-2016 Petrozavodsk Winter Training Camp, Nizhny Novgorod SU Contest B. Forcefield 题意 给你一维平面上n个镜子 ...
- 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】
2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...
- 2014-2015 Petrozavodsk Winter Training Camp, Contest.58 (Makoto rng_58 Soejima contest)
2014-2015 Petrozavodsk Winter Training Camp, Contest.58 (Makoto rng_58 Soejima contest) Problem A. M ...
- 【取对数】【哈希】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem J. Bobby Tables
题意:给你一个大整数X的素因子分解形式,每个因子不超过m.问你能否找到两个数n,k,k<=n<=m,使得C(n,k)=X. 不妨取对数,把乘法转换成加法.枚举n,然后去找最大的k(< ...
- 【BFS】【最小生成树】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem G. We Need More Managers!
题意:给你n个点,点带权,任意两点之间的边权是它们的点权的异或值中“1”的个数,问你该图的最小生成树. 看似是个完全图,实际上有很多边是废的.类似……卡诺图的思想?从读入的点出发BFS,每次只到改变它 ...
随机推荐
- 使用qt写的进制转换器
没有使用什么数据结构,直接使用qt自带的进制转换函数, 实时出结果,代码在后面的链接中,由于初学qt,好多不会,代码构造就有点乱 截图如下
- 关于oracle数据库死锁的检查方法
一.数据库死锁的现象程序在执行的过程中,点击确定或保存按钮,程序没有响应,也没有出现报错. 二.死锁的原理当对于数据库某个表的某一列做更新或删除等操作,执行完毕后该条语句不提交,另一条对于这一列数据做 ...
- Fiddler大师之路系列(一)
江湖传言,Fiddler是捕获客户端与服务器之间的所有HTTP(S) 请求的利器,但是在具体使用过程中,发现使用Fiddler进行抓包时有一部分请求总是没到,多方苦寻之下发现客户端使用WinINET这 ...
- C#基础学习之StreamReader和StreamWriter
StreamReader和StreamWriter操作字符的 FileStream操作字节的 //使用StreamReader读取文件 using (StreamReader sr=new Strea ...
- CKEDITOR的内容js转码,C#控制器解码接收
<script type="text/javascript" src="<%=Url.Content("~/Resource/ckeditor/ck ...
- Windows版Oracle重建EM---备注
前提条件添加环境变量 ORACLE_HOSTNAME=<主机名:如:DESKTOP-P6J1a>ORACLE_SID=orclORACLE_UNQNAME=orcl 执行删除命令 C:\U ...
- http请求与传参
这并不算是文章,暂时只做粗略地记录,以免忘记,因此会显得杂乱无章,随便抓了几个包和对postman截图,日后有空再完善 1.get方式 只有一种方式,那就是在url后面跟参数 2.post方式 1)表 ...
- java基础61 JavaScript循环语句之while、do...while、for及for...in循环(网页知识)
本文知识点(目录): 1.while循环语句 2.do...while循环语句 3.for循环语句 4.for...in循环语句 5.附录1(with语句) 6.附录2( ...
- css同时满足两个类名才有效果的写法
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- javaweb作业一
作业:Http全称叫什么?有什么特点?端口号是多少?超文本传输协议:(1)遵循请求/响应模型(2)http协议是一种无状态协议,请求/响应完成后,连接会断开.这时,服务器无法知道当前访问的用户是否是老 ...