小A是小B家的园丁。小B的家里有n棵树,第i棵树的横坐标为i。一天,小B交给小A一个任务,让他降低自己家中的某些树木的高度。这个任务对小A来说十分简单,因为他有一把极其锋利的斧头和一门独门砍树秘籍,能够轻易地砍断任何参天大树。小A的砍树方法有3种,都是沿着一条y=kx+b的直线砍一段区间的树,相同的方法k值相同。只用了一个下午,小A就完成了小B的任务。第二天,小B来视察小A的任务完成情况。小B想知道小A是否真的用心砍树,于是提出了q个询问,每次询问一段区间中最低的树的高度。小A当然是不会记住树木的砍伐情况的,他只知道自己按什么顺序,使用了什么方法,砍了哪个连续区间的树,而且区间都是互不包含的。现在小A想请你帮帮他,回答小B的询问。

输入格式:

第一行三个整数k1,k2,k3表示小A三种砍树方法的斜率值;
第二行一个数n,表示一共有n棵树;
第三行n个数hi,分别表示n棵树的高度;
第四行一个数m,表示小A一共进行了m次操作;
接下来m行,每行四个数L,R,p,b,表示用第p种方法,即用y=kp+b的直线砍[L,R]区间的树;
接下来一行一个数q,表示小B的询问数;
接下来q行,每行两个数L,R,表示询问[L,R]区间中最低的树的高度。

输出格式:

一共q行,每行一个数h表示对应的回答。

样例输入:

1 0 -1
4
10 30 20 1
2
3 4 2 5
1 3 3 10
2
1 2
2 3

样例输出:


数据范围:

n<=1000000,m<=500000

时间限制:

3s

空间限制:

64M

提示:

如下图,红色即为树的剩余部分。

线段树

对于三种砍伐方法,每种砍得过程中k都是一样,只是b不一样

但是对于对树木影响最大的一定是b最小的时候

那么对于h数组建出线段树,开出三个lazy标记,分别表示这三种k的最小b

并同时记录区间最小值

在pushdown时,要对k分类讨论

如果$k<0$,这次砍树的最低点在最右端

如果$k>0$,这次砍树的最低点在最左端

然后就是区间修改,区间询问

还有这道题空间开的很卡,要用动态开点的线段树写法

#include <bits/stdc++.h>
#define inf 1000000000
using namespace std;
const int MAXN=1000010;
int k[4],n,h[MAXN],m,q,w;
struct node
{
int la[3],MIN,ls,rs;
}sh[MAXN*2];
void pushup(int x)
{
sh[x].MIN=min(sh[sh[x].ls].MIN,sh[sh[x].rs].MIN);
}
void pushdown(int x,int l,int r)
{
int mid;
mid=(l+r)>>1;
for (int i=0;i<=2;i++)
{
if (sh[x].la[i]!=inf)
{
if (k[i]<0)//同上分类讨论
{
sh[sh[x].ls].MIN=min(sh[sh[x].ls].MIN,max(k[i]*mid+sh[x].la[i],0));
sh[sh[x].rs].MIN=min(sh[sh[x].rs].MIN,max(k[i]*r+sh[x].la[i],0));
}
else
{
sh[sh[x].ls].MIN=min(sh[sh[x].ls].MIN,max(k[i]*l+sh[x].la[i],0));
sh[sh[x].rs].MIN=min(sh[sh[x].rs].MIN,max(k[i]*(mid+1)+sh[x].la[i],0));
}
sh[sh[x].ls].la[i]=min(sh[sh[x].ls].la[i],sh[x].la[i]);//注意不是直接赋值,而是取最小值符合定义
sh[sh[x].rs].la[i]=min(sh[sh[x].rs].la[i],sh[x].la[i]);
sh[x].la[i]=inf;
}
}
}
int build(int ll,int rr)//动态开点
{
w++;
int now=w;
for (int i=0;i<=2;i++)
sh[now].la[i]=inf;
if (ll==rr)
{
sh[now].MIN=h[ll];
return now;
}
int mid;
mid=(ll+rr)>>1;
sh[now].ls=build(ll,mid);
sh[now].rs=build(mid+1,rr);
pushup(now);
return now;
}
void change(int x,int l,int r,int ll,int rr,int kind,int v)//区间修改
{
if (l>=ll && r<=rr)
{
if (v<sh[x].la[kind])
{
sh[x].la[kind]=v;
if (k[kind]>0)
sh[x].MIN=min(sh[x].MIN,max(l*k[kind]+v,0));
else
sh[x].MIN=min(sh[x].MIN,max(r*k[kind]+v,0));
}
return;
}
pushdown(x,l,r);
int mid;
mid=(l+r)>>1;
if (ll<=mid)
change(sh[x].ls,l,mid,ll,rr,kind,v);
if (rr>mid)
change(sh[x].rs,mid+1,r,ll,rr,kind,v);
pushup(x);
}
int query(int x,int l,int r,int ll,int rr)//区间查询
{
if (l>=ll && r<=rr)
return sh[x].MIN;
pushdown(x,l,r);
pushup(x);
int mid,ans;
ans=inf;
mid=(l+r)>>1;
if (ll<=mid)
ans=query(sh[x].ls,l,mid,ll,rr);
if (rr>mid)
ans=min(ans,query(sh[x].rs,mid+1,r,ll,rr));
return ans;
}
int main()
{
for (int i=0;i<=2;i++)
scanf("%d",&k[i]);
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&h[i]);
build(1,n);
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
int l,r,p,b;
scanf("%d%d%d%d",&l,&r,&p,&b);
change(1,1,n,l,r,p-1,b);
}
scanf("%d",&q);
for (int i=1;i<=q;i++)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",query(1,1,n,l,r));
}
}

XJOI 夏令营501-511NOIP训练14 砍树(2)的更多相关文章

  1. XJOI夏令营501训练1——分配工作

    传送门:QAQQAQ 题意:某公司有工作人员x1,x2,…,xn ,他们去做工作y1,y2,…,ym(n<=m) ,每个人都能做其中的几项工作,并且对每一项工作都有一个固定的效率.问能否找到一种 ...

  2. test20190729 夏令营NOIP训练14

    40+100+0=140. 基因光线 黑大帅统治古古怪界后,一直在玩一种很奇葩的游戏.在一个二维平面上,他先复制了n个小A,把他们放在不同的位置,然后射出一条ax+by+c=0的基因光线,宽度为d,即 ...

  3. 1369 xth 砍树

    1369 xth 砍树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description 在一个凉爽的夏夜,xth 和 ...

  4. wikioi1369 xth 砍树

    题目描述 Description 在一个凉爽的夏夜,xth 和 rabbit 来到花园里砍树.为啥米要砍树呢?是这样滴, 小菜儿的儿子窄森要出生了.Xth这个做伯伯的自然要做点什么.于是他决定带着 r ...

  5. xth 砍树(codevs 1369)

    题目描述 Description 在一个凉爽的夏夜,xth 和 rabbit 来到花园里砍树.为啥米要砍树呢?是这样滴,小菜儿的儿子窄森要出生了.Xth这个做伯伯的自然要做点什么.于是他决定带着rab ...

  6. codevs1369 xth 砍树(线段树)

    1369 xth 砍树  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 在一个凉爽的夏夜,xth 和 rabbi ...

  7. AC日记——砍树 codevs 1388

    1388 砍树  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 伐木工人米尔科需要砍倒M米长的木 ...

  8. codevs 1388 砍树

    时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题目描述 Description 伐木工人米尔科需要砍倒M米长的木材.这是一个对米尔科来说很容易的工作,因为他有一 ...

  9. {CSDN}{英雄会}{砍树、石子游戏}

    砍树 思路: 可以将题目意图转化为:给定一棵树,求其中最接近总权值一半的子树. DFS求每个节点的所有子节点的权值和,遍历每个节点,最接近总权值一半的即为答案.复杂度O(N). 石子游戏: 思路: 一 ...

随机推荐

  1. Java 文件 IO 操作

    window 路径分割符: \ 表示 windows 系统文件目录分割符 java 代码在 windows 下写某个文件的话需要下面的方式 D:\\soft\\sdclass.txt  其中一个单斜杠 ...

  2. JavaScript DOM三种创建元素的方式

    三种创建元素的方式: document.write() element.innerHTML document.createElement() 初始HTML内容: <button>btn&l ...

  3. JavaScript求数组中元素的最大值

    要求: 求数组[2,6,1,77,52,25,7]中的最大值. 实现思路: 声明一个保存最大元素的变量 max 默认最大值max定义为数组中的第一个元素arr[0] 遍历这个数组,把里面每个数组元素和 ...

  4. 【小白学PyTorch】21 Keras的API详解(上)卷积、激活、初始化、正则

    [新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑答疑解惑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx6450 ...

  5. 使用Android进行VR图像处理

    Source code at GitHub 介绍 VR或360图像,可以在耳机或在像谷歌街景这样的网站上观看是标准的JPG图像.你可以使用简单的Android图形处理技术,通过单独的移动设备或内部运行 ...

  6. 本地vue项目跨域服务器接口

    1,打开index.js文件,找到  proxyTable 参照下面链接的方法,你们可以去点赞 https://www.douban.com/note/704314260/?type=like#sep

  7. select函数详解(转)

    Select函数在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如connect. accept.recv或recvfrom这样的阻塞 ...

  8. 2016年 实验三 B2C模拟实验

    实验三 B2C模拟实验 [实验目的] 掌握网上购物的基本流程和B2C平台的运营 [实验条件] ⑴.个人计算机一台 ⑵.计算机通过局域网形式接入互联网. (3).奥派电子商务应用软件 [知识准备] 本实 ...

  9. 2014年 实验一  C2C个人拍卖

    实验一  C2C个人拍卖 --实战淘宝 [实验目的] 掌握网上拍卖的基本流程和拍卖平台的运营 [实验条件]⑴.个人计算机一台 ⑵.计算机通过局域网形式接入互联网. ⑶.常用浏览器. [知识准备] 本实 ...

  10. JS学习之路一

    1.准备 ①安装vscode 地址:https://vscode.en.softonic.com/ ②安装node.js node -v npm -v 地址:https://nodejs.org/zh ...