BZOJ.4293.[PA2015]Siano(线段树)
\(Description\)
有一片n亩的土地,要在这上面种草。
在每一亩土地上都种植了一种独一无二的草,其中,第\(i\)亩土地的草每天会长高\(a[i]\)厘米。
一共会进行\(m\)次收割,其中第\(i\)次收割在第\(d[i]\)天,并把所有高度大于等于\(b[i]\)的部分全部割去。求每次收割得到的草的高度总和是多少。

/*
无论怎么收割,长得快的草一定是不矮于长得慢的;而询问与下标无关
所以按生长速度排序,某一时刻的高度一定是递增的,这样就可以二分了
注意很多longlong
小于x直接输出0!
Reset在查询里!所以查询中要有PushUp!
*/
#include<cstdio>
#include<cctype>
#include<algorithm>
#define gc() getchar()
#define now node[rt]
#define lson node[node[rt].ls]
#define rson node[node[rt].rs]
typedef long long LL;
const int N=5e5+5;
LL A[N],sum[N];
struct Seg_Tree
{
int tot;
struct Node
{
LL maxn,sum,tag/*num of days*/,flag/*reset(>=0) or not(-1)*/;
int l,r,ls,rs;
Node() {flag=-1;}
}node[N<<1];
inline void PushUp(int rt)
{
now.sum = lson.sum + rson.sum;
now.maxn = rson.maxn;
// now.maxn = std::max(lson.maxn, rson.maxn);
}
inline void Reset(int rt,LL f)
{
now.sum=1LL*(now.r-now.l+1)*f, now.maxn=f;
now.tag=0, now.flag=f;
}
inline void Update(int rt,LL tg)
{
now.tag += tg;
now.sum += (sum[now.r]-sum[now.l-1])*tg;
now.maxn += A[now.r]*tg;//最大值肯定是最高的那个
}
void PushDown(int rt)
{
if(~now.flag)
{
Reset(now.ls,now.flag), Reset(now.rs,now.flag),
now.flag=-1;
}
if(now.tag)//reset后重新赋上的tag
{
Update(now.ls,now.tag), Update(now.rs,now.tag),
now.tag=0;
}
}
void Build(int l,int r)
{
int p=tot++;
node[p].l=l, node[p].r=r;
// node[p].tag=0, node[p].flag=-1;
if(l==r) ;
// node[p].ls = node[p].rs = -1,
// node[p].maxn = node[p].sum = A[l];
else
{
int m=l+r>>1;
node[p].ls=tot, Build(l,m);
node[p].rs=tot, Build(m+1,r);
// PushUp(p);
}
}
int Find(int rt,LL x)
{
if(now.l==now.r) return now.l;
PushDown(rt);
if(lson.maxn>=x) return Find(now.ls,x);
return Find(now.rs,x);
}
LL Query_Sum(int rt,int L,int R,LL x)//Reset N[L~R] to x
{
LL res=0;
if(L<=now.l && now.r<=R) {res=now.sum; Reset(rt,x); return res;}//!
PushDown(rt);
int m=now.l+now.r>>1;
if(L<=m) res=Query_Sum(now.ls,L,R,x);
if(m<R) res+=Query_Sum(now.rs,L,R,x);
PushUp(rt);//!
return res;
}
// LL Query_Sum(int rt,int p,LL x)//Reset N[L~R] to x
// {
// if(now.r < p) return 0;
// LL res;
// if(now.l >= p) {res=now.sum; Reset(rt,x); return res;}//!
// PushDown(rt);
// res=Query_Sum(now.ls,p,x)+Query_Sum(now.rs,p,x);
// PushUp(rt);
// return res;
// }
}t;
#undef now
inline LL read()
{
LL now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("4293.in","r",stdin);
#endif
LL n=read(),m=read();
for(int i=1; i<=n; ++i) A[i]=read();
std::sort(A+1,A+1+n);
t.Build(1,n);
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+A[i];
for(LL res,day,x,las=0,pos; m; --m,las=day)
{
day=read(),x=read();
t.Update(0, day-las);
if(t.node[0].maxn < x) {puts("0"); continue;}//很有效 and必须要加!
pos=t.Find(0,x), printf("%lld\n",t.Query_Sum(0,pos,n,x)-(n-pos+1)*x);//longlong
// pos=t.Find(0,x), printf("%lld\n",t.Query_Sum(0,pos,x)-(n-pos+1)*x);//longlong
}
return 0;
}
BZOJ.4293.[PA2015]Siano(线段树)的更多相关文章
- 【BZOJ4293】[PA2015]Siano 线段树
[BZOJ4293][PA2015]Siano Description 农夫Byteasar买了一片n亩的土地,他要在这上面种草. 他在每一亩土地上都种植了一种独一无二的草,其中,第i亩土地的草每天会 ...
- BZOJ4293 [PA2015]Siano(线段树)
传送门 这Seg确实不好写,不过因为它与ai的相对顺序无关,所以,我们在对ai排序之后,就可做了.维护一个区间最大值,维护一个和,维护一个区间赋值的懒标记,再维护一个时间变化的标记就可以了. 因为不论 ...
- 【BZOJ】4293: [PA2015]Siano 线段树上二分
[题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解] ...
- Bzoj 2752 高速公路 (期望,线段树)
Bzoj 2752 高速公路 (期望,线段树) 题目链接 这道题显然求边,因为题目是一条链,所以直接采用把边编上号.看成序列即可 \(1\)与\(2\)号点的边连得是. 编号为\(1\)的点.查询的时 ...
- BZOJ.3938.Robot(李超线段树)
BZOJ UOJ 以时间\(t\)为横坐标,位置\(p\)为纵坐标建坐标系,那每个机器人就是一条\(0\sim INF\)的折线. 用李超线段树维护最大最小值.对于折线分成若干条线段依次插入即可. 最 ...
- BZOJ.1558.[JSOI2009]等差数列(线段树 差分)
BZOJ 洛谷 首先可以把原序列\(A_i\)转化成差分序列\(B_i\)去做. 这样对于区间加一个等差数列\((l,r,a_0,d)\),就可以转化为\(B_{l-1}\)+=\(a_0\),\(B ...
- BZOJ 3779: 重组病毒(线段树+lct+树剖)
题面 escription 黑客们通过对已有的病毒反编译,将许多不同的病毒重组,并重新编译出了新型的重组病毒.这种病毒的繁殖和变异能力极强.为了阻止这种病毒传播,某安全机构策划了一次实验,来研究这种病 ...
- BZOJ 3123 森林(函数式线段树)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=3123 题意: 思路:总的来说,查询区间第K小利用函数式线段树的减法操作.对于两棵树的合并 ...
- BZOJ 2124等差子序列 线段树&&hash
[题目描述 Description] 给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4<p5<…<pLen<=N(Len& ...
随机推荐
- GCC编译过程与动态链接库和静态链接库
1. 库的介绍 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常. 本质上来说库是一种可执行代码的二进制形式,可 ...
- linux 查看cpu的使用百分比
先安装 sudo apt-get install sysstat 然后: mpstat -u 2 5
- 在Ubuntu中通过update-alternatives切换软件版本
update-alternatives是ubuntu系统中专门维护系统命令链接符的工具,通过它可以很方便的设置系统默认使用哪个命令.哪个软件版本,比如,我们在系统中同时安装了open jdk和sun ...
- mysql5.6.13通用二进制格式安装并使用amoeba实现对mysql5.6数据库读写分离
proxy 192.168.8.39 master 192.168.8.40 slave 192.168.8.20 一.安装mysql-5.6.13服务器 安装包: mysql-5.6.13-linu ...
- Java中日期格式化SimpleDateFormat类包含时区的处理方法
1.前言 需要把格式为“2017-02-23T08:04:02+01:00”转化成”23-02-2017-T15:04:02“格式(中国时区为+08:00所以是15点),通过网上查找答案,发现没有我需 ...
- Dotfuscator使用
参考:https://www.cnblogs.com/xiezunxu/articles/7228741.html
- PYTHON-模块time&datetime+ 目录规范
1.目录规范 ***** (1)文件夹的规范写法 bin 可执行文件 conf 配置文件 core 主要业务逻辑 db 数据文件 lib 库 (公共代码 第三方模块) log 日志文件 readme ...
- shell expect权威指南和实战
一.概述 我们通过Shell可以实现简单的控制流功能,如:循环.判断等.但是对于需要交互的场合则必须通过人工来干预,有时候我们可能会需要实现和交互程序如telnet服务器等进行交互的功能.而expec ...
- Java连接oracle数据库的两种常用方法
1. 使用thin连接 由于thin驱动都是纯Java代码,并且使用TCP/IP技术通过java的Socket连接上Oracle数据库,所以thin驱动是与平台无关的,你无需安装Oracle客户端,只 ...
- OneNET麒麟座应用开发之二:串口读取PM25传感器数据
作为环境数据监测站首先要获取大气中可吸入颗粒物的数据.为了检测PM25数据,我们采用北京海联信为的HLPM025K3型号传感器,该传感器使用激光法测量PM25和PM10的数据. 该型传感器的检测对象如 ...