2018.07.23[PA2015]Siano(线段树)
[PA2015]Siano
描述
Description
农夫Byteasar买了一片n亩的土地,他要在这上面种草。 他在每一亩土地上都种植了一种独一无二的草,其中,第i亩土地的草每天会长高a[i]厘米。 Byteasar一共会进行m次收割,其中第i次收割在第d[i]天,并把所有高度大于等于b[i]的部分全部割去。Byteasar想知道,每次收割得到的草的高度总和是多少,你能帮帮他吗?
输入
Input
第一行包含两个正整数n,m(1<=n,m<=500000),分别表示亩数和收割次数。 第二行包含n个正整数,其中第i个数为ai,依次表示每亩种植的草的生长能力。 接下来m行,每行包含两个正整数d[i],bi,依次描述每次收割。 数据保证d[1]
输出
Output
输出m行,每行一个整数,依次回答每次收割能得到的草的高度总和。
样例输入
4 4
1 2 4 3
1 1
2 2
3 0
4 4
样例输出
6
6
18
0
提示
第1天,草的高度分别为1,2,4,3,收割后变为1,1,1,1。
第2天,草的高度分别为2,3,5,4,收割后变为2,2,2,2。
第3天,草的高度分别为3,4,6,5,收割后变为0,0,0,0。
第4天,草的高度分别为1,2,4,3,收割后变为1,2,4,3。
Source
By Claris
标签
BZOJ4293
不难发现如果将a[i]" role="presentation" style="position: relative;">a[i]a[i]排序,每次割完草后剩下的草的高度仍然是单调不减的。这样的话,我们维护线段树区间覆盖,区间加,区间和,维护查询区间内刚好小于等于某个数的下标。这样的话将割草拆成区间加之后查询区间内刚好小于等于某个数的下标,然后再讲大于割草高度的全部区间覆盖成割草高度,然后比较覆盖前后的区间和就行了。
代码如下:
#include<bits/stdc++.h>
#define ll long long
#define N 500005
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
using namespace std;
inline ll read(){
ll ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
int n,m;
ll d1,a[N],sum[N];
struct Node{int l,r;ll maxn,sum,lz,bz;}T[N<<2];
inline ll max(ll a,ll b){return a>b?a:b;}
inline void pushup(int p){T[p].maxn=max(T[lc].maxn,T[rc].maxn),T[p].sum=T[lc].sum+T[rc].sum;}
inline void pushnow(int p,ll v){T[p].sum+=v*(sum[T[p].r]-sum[T[p].l-1]),T[p].maxn+=v*a[T[p].r],T[p].lz+=v;}
inline void pushnown(int p,ll v){T[p].bz=v,T[p].lz=0,T[p].sum=(T[p].r-T[p].l+1)*v,T[p].maxn=v;}
inline void pushdown(int p){
if(T[p].bz!=-1)pushnown(lc,T[p].bz),pushnown(rc,T[p].bz),T[p].bz=-1;
if(T[p].lz)pushnow(lc,T[p].lz),pushnow(rc,T[p].lz),T[p].lz=0;
}
inline void build(int p,int l,int r){
T[p].l=l,T[p].r=r,T[p].lz=0,T[p].bz=-1;
if(l==r){T[p].sum=T[p].maxn=0;return;}
build(lc,l,mid),build(rc,mid+1,r);
}
inline void modify(int p,int ql,int qr,ll v){
if(ql>T[p].r||qr<T[p].l)return;
if(ql<=T[p].l&&T[p].r<=qr){pushnown(p,v);return;}
pushdown(p);
if(qr<=mid)modify(lc,ql,qr,v);
else if(ql>mid)modify(rc,ql,qr,v);
else modify(lc,ql,mid,v),modify(rc,mid+1,qr,v);
pushup(p);
}
inline ll query(int p,ll v){
if(T[p].l==T[p].r)return T[p].l;
pushdown(p);
if(T[lc].maxn<=v)return query(rc,v);
return query(lc,v);
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;++i)a[i]=read();
sort(a+1,a+n+1);
build(1,1,n);
for(int i=1;i<=n;++i)sum[i]=sum[i-1]+a[i];
d1=0;
while(m--){
ll d2=read(),b=read();
T[1].maxn+=(d2-d1)*a[n],T[1].sum+=(d2-d1)*sum[n],T[1].lz+=(d2-d1);
if(T[1].maxn<=b){puts("0"),d1=d2;continue;}
ll tmp=T[1].sum;
int pos=query(1,b);
modify(1,pos,n,b);
cout<<tmp-T[1].sum<<'\n',d1=d2;
}
return 0;
}
2018.07.23[PA2015]Siano(线段树)的更多相关文章
- 【BZOJ4293】[PA2015]Siano 线段树
[BZOJ4293][PA2015]Siano Description 农夫Byteasar买了一片n亩的土地,他要在这上面种草. 他在每一亩土地上都种植了一种独一无二的草,其中,第i亩土地的草每天会 ...
- BZOJ4293 [PA2015]Siano(线段树)
传送门 这Seg确实不好写,不过因为它与ai的相对顺序无关,所以,我们在对ai排序之后,就可做了.维护一个区间最大值,维护一个和,维护一个区间赋值的懒标记,再维护一个时间变化的标记就可以了. 因为不论 ...
- 2018.07.22 codeforces750E(线段树维护状态转移)
传送门 给出一个数字字串,给出若干个询问,询问在字串的一段区间保证出现2017" role="presentation" style="position: re ...
- BZOJ.4293.[PA2015]Siano(线段树)
题目链接 \(Description\) 有一片n亩的土地,要在这上面种草. 在每一亩土地上都种植了一种独一无二的草,其中,第\(i\)亩土地的草每天会长高\(a[i]\)厘米. 一共会进行\(m\) ...
- 2018.07.23 codeforces 438D. The Child and Sequence(线段树)
传送门 线段树维护区间取模,单点修改,区间求和. 这题老套路了,对一个数来说,每次取模至少让它减少一半,这样每次单点修改对时间复杂度的贡献就是一个log" role="presen ...
- 2018.07.23 洛谷P4097 [HEOI2013]Segment(李超线段树)
传送门 给出一个二维平面,给出若干根线段,求出x" role="presentation" style="position: relative;"&g ...
- 2018.07.23 hdu5828 Rikka with Sequence(线段树)
传送门 这道题维护区间加,区间开根,区间求和. 线段树常规操作. 首先回忆两道简单得多的线段树. 第一个:区间覆盖,区间加,区间求和. 第二个:区间开根,区间求和. 这两个是名副其实的常规操作. 但这 ...
- 2018.07.23 洛谷P4513 小白逛公园(线段树)
传送门 线段树常规操作了解一下. 单点修改维护区间最大连续和. 对于一个区间,维护区间从左端点开始的连续最大和,从右端点开始的连续最大和,整个区间最大和,区间和. 代码如下: #include< ...
- HDU 6356 Glad You Came 2018 Multi-University Training Contest 5 (线段树)
题目中没有明说会爆int和longlong 的精度,但是在RNG函数中不用unsigned int 会报精度,导致队友debug了很久... 根据每次生成的l,r,v对区间更新m次,然后求 i*ai的 ...
随机推荐
- win10 ubuntu双系统安装后无法引导进入ubuntu
之前按照先装windows后装ubuntu的方式装的系统,都可以引导到ubuntu,无论是将ubuntu挂在到/boot在windows用easy BCD建立ubuntu引导,还是将ubuntu挂在到 ...
- ubuntu 软件包系统已损坏 解决方法
sudo apt-get clean sudo apt-get -f install sudo apt-get upgrade
- 关于frameset与iframe的使用
<frameset>与<body>标签同级,是不能同时存在的,<frameset>是把当前页面进行分割. frameset.html: <!DOCTYPE h ...
- too few PGs per OSD (20 < min 30)
ceph osd pool set replicapool pg_num 150 ceph osd pool set replicapool pgp_num 150
- Web标准:八、下拉及多级弹出菜单
Web标准:八.下拉及多级弹出菜单 知识点: 1.带下拉子菜单的导航菜单 2.绝对定位和浮动的区别和运用 3.CSS自适应宽度滑动门菜单 1)带下拉子菜单的导航菜单 带下拉子菜单的就是在一级导航下 ...
- string类小结
要想使用标准C++中string类,必须要包含 #include <string>// 注意是<string>,不是<string.h>,带.h的是C语言中的头文件 ...
- js字符串解析成数字
parseInt() 先把参数转换成字符串:左边有连续的数字则返回数值,若没有则返回NaN. console.log('parseInt(null)',parseInt(null)); // NaN ...
- OC - runtime - 1
- Mybatis的分页插件PageHelp:Page对象中的pageSize等属性无法序列化,无法转换为json字符串
Page<User> page = new Page<>(); User user = new User(); user.setAge(20); ...
- MyEclipse2018.9.0设置全局编码
1.windows->Preferences打开"首选项"对话框,左侧导航,导航到general->Workspace 右侧Text file encoding,选择O ...