59  懒惰的奶牛
贝西所在的牧场,散落着 N 堆牧草,其中第 i 堆牧草在 ( Xi,Yi ) 的位置,数量有 Ai 个单位。
贝西从家移动到某一堆牧草的时候,只能沿坐标轴朝正北、正东、正西、正南这四个方向移
动,所以计算贝西和牧草间的距离时,应采用“曼哈顿距离”—— (x,y ) 和 (x ,y ) 之间的距离为
|x x | + |y y |。例如贝西的家在 (0.5, 0.3),有一堆牧草在 (3, 2),那么它们之间的距离就是 4.2。
贝西懒得走动,她想请你为它寻找一个最好的位置作为家,这个家附近距离不超过 K 的牧草数
量之和是最大的。注意家的坐标可以不是整数,也可以和某堆牧草的坐标完全重合。
输入格式
• 第一行:两个整数 N K, 1 N 100000, 1 K 2000000
• 第二行到第 N + 1 行:第 i + 1 行有三个整数: Ai, Xi Yi, 1 Ai 10000, 0 Xi,Yi
1000000
输出格式
• 单个整数:表示距离和最佳位置不超过 K 的牧草数量之和
样例输入
4 3
7 8 6
3 0 0
4 6 0
1 4 2
样例输出
8
解释
选择 (3, 0) 为家,位置在 (0, 0), (6, 0) 和
(4, 2) 的牧草距离家都不超过 K
来源
The Lazy Cow, 2014 Mar

【分析】

  曼哈顿距离的话,那个范围,应该是一个边长和坐标轴呈45度角的正方形。

  这样就有点难搞,难统计。

  我们需要把图形“旋转一下”

  旋转的目标是让正方形的边长平行于坐标轴。、

  那么,观察一下可以得到,可以把nx=x-y ny=x+y 这样就旋转过来了(其实改变了正方形的大小的,但没有关系,只要能判断出曼哈顿距离是不是<=k就好)

 然后就很简单了,用线段树维护y纵坐标,然后x横坐标线性扫描。

代码如下:

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define Maxn 2000010 struct hp
{
int a,ax,ay;
}tt[Maxn]; struct node
{
int l,r,lc,rc,ans;
int lazy;
}t[*Maxn];int len; int mymin(int x,int y) {return x<y?x:y;}
int mymax(int x,int y) {return x>y?x:y;} bool cmp(hp x,hp y) {return x.ax<y.ax;}
int n,k; int build(int l,int r)
{
int x=++len;
t[x].l=l;t[x].r=r;
t[x].ans=;t[x].lazy=;
if(l!=r)
{
int mid=(l+r)>>;
t[x].lc=build(l,mid);
t[x].rc=build(mid+,r);
}
else t[x].lc=t[x].rc=;
return x;
} void init()
{
scanf("%d%d",&n,&k);
int mx=;
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&tt[i].a,&tt[i].ax,&tt[i].ay);
int xx=tt[i].ax;
tt[i].ax=tt[i].ax-tt[i].ay;tt[i].ay=xx+tt[i].ay+;
mx=mymax(mx,tt[i].ay);
}
sort(tt+,tt++n,cmp);
k=k*;
build(,mx);
} void upd(int x)
{
if(t[x].lazy==) return;
t[x].ans+=t[x].lazy;
int lc=t[x].lc,rc=t[x].rc;
if(t[x].l!=t[x].r)
{
t[lc].lazy+=t[x].lazy;
t[rc].lazy+=t[x].lazy;
}
t[x].lazy=;
} void change(int x,int l,int r,int y)
{
if(t[x].l==l&&t[x].r==r)
{
t[x].lazy+=y;
return;
}
upd(x);
int mid=(t[x].l+t[x].r)>>;
if(r<=mid) change(t[x].lc,l,r,y);
else if(l>mid) change(t[x].rc,l,r,y);
else
{
change(t[x].lc,l,mid,y);
change(t[x].rc,mid+,r,y);
}
upd(t[x].lc);upd(t[x].rc);
t[x].ans=mymax(t[t[x].lc].ans,t[t[x].rc].ans);
} void ffind()
{
int j=,ans=;
for(int i=;i<=n;i++)
{
while(j<n&&tt[j+].ax-tt[i].ax<=k)
{
int nx=mymax(,tt[j+].ay-k);
change(,nx,tt[j+].ay,tt[j+].a);
j++;
}
upd();
ans=mymax(ans,t[].ans);
change(,mymax(,tt[i].ay-k),tt[i].ay,-tt[i].a);
}
printf("%d\n",ans);
} int main()
{
init();
ffind();
return ;
}

bzoj 3476

2016-10-31 11:25:57

【BZOJ 3476】 线段树===的更多相关文章

  1. BZOJ 1798 (线段树||分块)的标记合并

    我原来准备做方差的.. 结果发现不会维护两个标记.. 就是操作变成一个 a*x+b ,每次维护a , b 即可 加的时候a=1 ,b=v 乘的时候a=v ,b=0 #include <cstdi ...

  2. bzoj 3999 线段树区间提取 有序链剖

    看错题目了,想成每个城市都可以买一个东西,然后在后面的某个城市卖掉,问最大收益.这个可以类似维护上升序列的方法在O(nlog^3n)的时间复杂度内搞定 这道题用到的一些方法: 1. 可以将有关的线段提 ...

  3. bzoj 3211 线段树

    开方操作最多进行5次就可以把出现的任何数变成1. 所以用线段树暴力修改,以后修改时只需看一下是否当前区间都是0或1,如果是那么就直接返回. /***************************** ...

  4. bzoj 1018 线段树维护连通性

    本题将一道LCT的题特殊化(支持加边和删边,询问图的连通性),将图变成了2×m的网格图,然后就神奇地可以用线段树来维护. 对于每个区间[l,r],维护其四个角落之间的连通性(仅仅通过[l,r]这段的边 ...

  5. bzoj 3212 线段树

    裸的线段树 /************************************************************** Problem: User: BLADEVIL Langua ...

  6. bzoj 2120 线段树套平衡树

    先吐下槽,改了快一个小时,最后发现是SBT的delete写错了,顿时就有想死的心..... 首先对于这道题,我们应该先做一下他的小问题,bzoj1878,虽然和这道题几乎一点关系没有, 但是能给我们一 ...

  7. bzoj 1901 线段树套平衡树+二分答案查询

    我们就建一颗线段树,线段树的每一个节点都是一颗平衡树,对于每个询问来说,我们就二分答案, 查询每个二分到的mid在这个区间里的rank,然后就行了 /************************* ...

  8. BZOJ 1012 线段树||单调队列

    非常裸的线段树  || 单调队列: 假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值. 既然它仅仅在末尾选.那么自然能够满足以上的条件 ...

  9. BZOJ 3681 线段树合并+网络流

    思路: 暴力建图有n*m条边 考虑怎么优化 (那就只能加个线段树了呗) 然后我就不会写了..... 抄了一波题解 //By SiriusRen #include <bits/stdc++.h&g ...

  10. BZOJ 4756 线段树合并(线段树)

    思路: 1.最裸的线段树合并 2. 我们可以观察到子树求一个东西 那我们直接DFS序好了 入队的时候统计一下有多少比他大的 出的时候统计一下 减一下 搞定~ 线段树合并代码: //By SiriusR ...

随机推荐

  1. Vim常见快捷键汇总

    编辑命令: i 词前插入 a 词后插入 I 行首插入 A 行尾插入 o 新建一行编辑 O 在上面新建一行 插入: 10 i * [ESC] 插入10个* 25 a xx [ESC] 插入25个xx J ...

  2. 练习PopupWindow弹出框之实现界面加载的时候显示弹出框到指定的view下面--两种延迟方法

    今天在练习PopupWindow弹出框的时候,打算在界面加载的时候将弹出框展现出来并显示在指定的view下面. 初步方法是直接在OnResume方法里面直接执行showPopupWindows方法. ...

  3. java Spring 在WEB应用中的实例化

    .前面讲解的都是通过直接读取配置文件,进行的实例化ApplicationContext AbstractApplicationContext app = new ClassPathXmlApplica ...

  4. 主机访问 虚拟机web注意事项

    在这里, 我通过NAT的方式, 通过主机访问虚拟机. 需要做的是, 将主机中访问的端口, 映射为虚拟机的'编辑->虚拟网络编辑器->vmnet8', 如下图 在弹出的'映射传入端口'界面中 ...

  5. A题笔记(14)

    Reverse Words in a String : http://oj.leetcode.com/problems/reverse-words-in-a-string/ 代码 : https:// ...

  6. js【输入一个日期】返回【当前12个月每月最后一天】

    Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.getMonth() + ...

  7. C语言链表全操作(增,删,改,查,逆序,递增排序,递减排序,链式队列,链式栈)

    一,数据结构——链表全操作: 链表形式: 其中,每个节点(Node)是一个结构体,这个结构体包含数据域,指针域,数据域用来存放数据,指针域则用来指向下一个节点: 特别说明:对于单链表,每个节点(Nod ...

  8. Codevs 1217 借教室 2012年NOIP全国联赛提高组

    1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...

  9. stringstream vs sprintf, sscanf.

    前言 以前一直认为 stringstream 远不如 sprintf. 近日突然萌发了看看 stirngstream 是不是真的如我想的那么烂 对比 // stringstream. stringst ...

  10. 数据结构学习——shell排序的C语言实现

    shell排序: 这个排序的命名是来自发明者的名字,和排序的方法没有字面上的联系.所以不要因为名字而感觉很难.在K&R的C程序设计语言中书中只用了几行代码很简洁的实现了这个排序算法.那就来看看 ...