【bzoj3476-懒惰的奶牛】线段树

题解:
感觉这题和别人的做法不一样。。。呵呵呵。。。调了一百年。。
设家坐标为(a,b),对于每个点(x,y),可以转化为|a-x|+|b-y|<=k
对于每个点,它的影响范围是一个菱形(也就是一个正方形啦。。),也就是一个图上有若干个正方形。

然后我就把这个坐标轴选择了45度。
好难画不画了,正交分解一下就可以了。
然后题目就转化成正方形各种交里的最大值。

正方形有x和y两个元素,但是很明显我们只能维护一个。。
所以我以x轴建立线段树,对于每个正方形按照y从小到大排序。
维护一个指针j,表示当前前j个正方形已经和现在在处理的第i个正方形没有交集。每次都要先把j更新(看看它是否能后移)。
然后我们在当前正方形的两端a[i].x~a[i].y这一段+a[i].d
每个点维护当前的和d以及该区间的最大值mx。每次做完之后,用t[1].mx更新答案。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<ctime>
#include<queue>
#include<algorithm>
using namespace std; const int N=,INF=(int)1e9;
int n,K,L,tl,ans;
struct trnode{
int l,r,lc,rc,d,mx,lazy;
}t[*N];
struct node{
int x,y,d;
}a[N]; bool cmp(node x,node y){return x.y<y.y;}
int maxx(int x,int y){return x>y ? x:y;}
int minn(int x,int y){return x<y ? x:y;} int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-; ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-''; ch=getchar();}
return x*f;
} int bt(int l,int r)
{
int x=++tl;
t[x].l=l;t[x].r=r;
t[x].lc=t[x].rc=;
t[x].mx=;t[x].d=;
t[x].lazy=;
if(l<r)
{
int mid=(l+r)/;
t[x].lc=bt(l,mid);
t[x].rc=bt(mid+,r);
}
return x;
} void pd(int x)
{
if(t[x].lazy==) return ;
int d=t[x].lazy,lc=t[x].lc,rc=t[x].rc;
t[x].lazy=;
t[x].d+=d;
t[x].mx+=d;
if(lc) t[lc].lazy+=d;
if(rc) t[rc].lazy+=d;
} void change(int x,int l,int r,int d)
{
pd(x);
if(t[x].l==l && t[x].r==r)
{
t[x].lazy+=d;
pd(x);
return ;
}
int lc=t[x].lc,rc=t[x].rc,mid=(t[x].l+t[x].r)/;
if(r<=mid) change(lc,l,r,d);
else if(l>mid) change(rc,l,r,d);
else
{
change(lc,l,mid,d);
change(rc,mid+,r,d);
}
pd(x);pd(lc);pd(rc);
t[x].mx=maxx(t[lc].mx,t[rc].mx);
} int main()
{
// freopen("a.in","r",stdin);
// freopen("me.out","w",stdout);
freopen("lazy.in","r",stdin);
freopen("lazy.out","w",stdout);
n=read();K=read();
// scanf("%d%d",&n,&K);
int x,y,tx,ty,nx=INF,ny=INF,mx=;tl=;L=*K;
for(int i=;i<=n;i++)
{
a[i].d=read();x=read();y=read();
// scanf("%d%d%d",&a[i].d,&x,&y);
tx=x,ty=y+K;
a[i].x=tx-ty;
a[i].y=tx+ty; nx=minn(nx,a[i].x);
ny=minn(ny,a[i].y);
}
for(int i=;i<=n;i++)
{
a[i].x-=nx-;
a[i].y-=ny-;
mx=maxx(mx,a[i].x);
}
mx+=;ans=;
sort(a+,a++n,cmp);
bt(,mx);
int j=;
change(,a[].x,minn(mx,a[].x+L),a[].d);
ans=maxx(ans,t[].mx);
for(int i=;i<=n;i++)
{
while(j<i && a[i].y-L>a[j].y)
{
change(,a[j].x,minn(mx,a[j].x+L),-a[j].d);
ans=maxx(ans,t[].mx);
j++;
}
change(,a[i].x,minn(mx,a[i].x+L),a[i].d);
ans=maxx(ans,t[].mx);
}
printf("%d\n",ans);
return ;
}
【bzoj3476-懒惰的奶牛】线段树的更多相关文章
- Codeforces 444C 线段树 懒惰标记
前天晚上的CF比赛div2的E题,很明显一个线段树,当时还在犹豫复杂度的问题,因为他是区间修改和区间查询,肯定是要用到懒惰标记. 然后昨天真的是给这道题跪了,写了好久好久,...我本来是写了个add标 ...
- D - Mayor's posters(线段树+离散化)
题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...
- 【HDU 4614】Vases and Flowers(线段树区间更新懒惰标记)
题目0到n-1的花瓶,操作1在下标a开始插b朵花,输出始末下标.操作2清空[a,b]的花瓶,求清除的花的数量.线段树懒惰标记来更新区间.操作1,先查询0到a-1有num个空瓶子,然后用线段树的性质,或 ...
- 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- 【HDU】4092 Nice boat(多校第四场1006) ——线段树 懒惰标记
Nice boat Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) To ...
- poj3468 线段树的懒惰标记
题目链接:poj3468 题意:给定一段数组,有两种操作,一种是给某段区间加c,另一种是查询一段区间的和 思路:暴力的方法是每次都给这段区间的点加c,查询也遍历一遍区间,复杂度是n*n,肯定过不去,另 ...
- HDU 4107 Gangster(线段树 特殊懒惰标记)
两种做法. 第一种:标记区间最大值和最小值,若区间最小值>=P,则本区间+2c,若区间最大值<P,则本区间+c.非常简单的区间更新. 最后发一点牢骚:最后query查一遍就行,我这个2B竟 ...
- POJ 3468 线段树 成段更新 懒惰标记
A Simple Problem with Integers Time Limit:5000MS Memory Limit:131072K Case Time Limit:2000MS Descr ...
- Transformation HDU - 4578(线段树——懒惰标记的妙用)
Yuanfang is puzzled with the question below: There are n integers, a 1, a 2, …, a n. The initial val ...
随机推荐
- Java中I/O流之数据流
Java 中的数据流: 对于某问题:将一个 long 类型的数据写到文件中,有办法吗? 转字符串 → 通过 getbytes() 写进去,费劲,而且在此过程中 long 类型的数需要不断地转换. ...
- animate.css与wow.js制作网站动效
animate.css 官网:https://daneden.github.io/animate.css/ 包括:attention seekers:关注者 bouncing entrances:跳跃 ...
- Centos安装TFTP/NFS/PXE服务器网络引导安装系统
客户端网卡要求支持以PXE启动,配置都在服务端进行,通过PXE网络启动安装系统流程: 客户端以PXE启动发送DHCP请求: 服务器DHCP应答,包括客户端的IP地址,引导文件所在TFTP服务器: 客户 ...
- [CLR via C#]引用类型和值类型
一.引用类型与值类型的区别 CLR支持两种类型:引用类型和值类型.引用类型总是从托管堆上分配的,C#的new操作符会返回对象的内存地址.使用引用类型时,必须注意到一些性能问题. 1)内存必须从托管堆上 ...
- c++读取文件夹及子文件夹数据
这里有两种情况:读取文件夹下所有嵌套的子文件夹里的所有文件 和 读取文件夹下的指定子文件夹(或所有子文件夹里指定的文件名) <ps,里面和file文件有关的结构体类型和方法在 <io.h ...
- Java ArrayList Vector LinkedList Stack Hashtable等的差别与用法(转)
ArrayList 和Vector是采取数组体式格式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,都容许直接序号索引元素,然则插入数据要设计到数组元素移动等内存操纵,所以索引数据快插入数 ...
- [Leetcode] 3.Longest Substring Without Repeating Characters(unordered_map)
通过把未访问的结点放到unordered_map中来判断是否重复,代码如下: class Solution { public: int lengthOfLongestSubstring(string ...
- 【Python】python和json数据相互转换,json读取和写入,repr和eval()使用
python数据转换json 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import jso ...
- [转]MATLAB cell数据类型
细胞型数据类型(cell)使不同类型和不同维数的数组可以共存,细胞型数组实际上可以认为是一种以任意形式的数组为分量的多维数组. 1.细胞型数据的定义 1)直接赋值定义:细胞型变量在定义时需要使用大括号 ...
- Codeforces 1025D(区间dp)
容易想到设f[i][j][k]为i~j区间以k为根是否能构成bst.这样是O(n4)的.考虑将状态改为f[i][j][0/1]表示i~j区间以i-1/j+1为根能否构成bst.显然如果是i-1作为根的 ...