【BZOJ4293】[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个数为a[i](1<=a[i]<=1000000),依次表示每亩种植的草的生长能力。
接下来m行,每行包含两个正整数d[i],b[i](1<=d[i]<=10^12,0<=b[i]<=10^12),依次描述每次收割。
数据保证d[1]<d[2]<...<d[m],并且任何时刻没有任何一亩草的高度超过10^12。

Output

输出m行,每行一个整数,依次回答每次收割能得到的草的高度总和。

Sample Input

4 4
1 2 4 3
1 1
2 2
3 0
4 4

Sample Output

6
6
18
0

HINT

第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。

题解:有一个容易发现的性质:长得快的草永远不会比长得慢的草矮。

所以先按ai排序,然后每次只需要二分一个边界,长得比这个边界快的草都会被割掉。然后用线段树维护即可。

但是具体实现不是那么方便,我们的线段树需要维护:带系数的区间加,区间赋值,区间求和,区间求最大值。细节还是看代码吧~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lson x<<1
#define rson x<<1|1
using namespace std;
typedef long long ll;
const int maxn=500010;
int n,m;
ll A[maxn],B,D[maxn],s[maxn<<2],sm[maxn<<2],siz[maxn<<2],ts[maxn<<2],tag[maxn<<2];
void pushup(int x)
{
s[x]=s[lson]+s[rson],sm[x]=min(sm[lson],sm[rson]);
}
void pushdown(int l,int r,int x)
{
int mid=l+r>>1;
if(~tag[x])
{
ts[lson]=ts[rson]=0,tag[lson]=tag[rson]=sm[lson]=sm[rson]=tag[x];
s[lson]=(mid-l+1)*tag[x],s[rson]=(r-mid)*tag[x];
tag[x]=-1;
}
if(ts[x])
{
ts[lson]+=ts[x],ts[rson]+=ts[x];
s[lson]+=siz[lson]*ts[x],sm[lson]+=A[l]*ts[x],s[rson]+=siz[rson]*ts[x],sm[rson]+=A[mid+1]*ts[x];
ts[x]=0;
}
}
void build(int l,int r,int x)
{
tag[x]=-1;
if(l==r)
{
siz[x]=A[l];
return ;
}
int mid=l+r>>1;
build(l,mid,lson),build(mid+1,r,rson);
siz[x]=siz[lson]+siz[rson];
}
ll updata(int l,int r,int x,int a,int b,ll c)
{
if(a<=l&&r<=b)
{
ll ret=s[x]-(r-l+1)*c;
ts[x]=0,sm[x]=tag[x]=c,s[x]=(r-l+1)*c;
return ret;
}
pushdown(l,r,x);
int mid=l+r>>1;
ll ret=0;
if(a<=mid) ret+=updata(l,mid,lson,a,b,c);
if(b>mid) ret+=updata(mid+1,r,rson,a,b,c);
pushup(x);
return ret;
}
int getpre(int l,int r,int x,ll a)
{
if(sm[x]>=a) return l-1;
if(l==r) return l;
pushdown(l,r,x);
int mid=l+r>>1;
if(sm[rson]<a) return getpre(mid+1,r,rson,a);
return getpre(l,mid,lson,a);
}
ll rd()
{
ll ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd();
int i;
for(i=1;i<=n;i++) A[i]=rd();
sort(A+1,A+n+1);
build(1,n,1);
for(i=1;i<=m;i++)
{
D[i]=rd(),B=rd();
ts[1]+=D[i]-D[i-1],s[1]+=siz[1]*(D[i]-D[i-1]),sm[1]+=A[1]*(D[i]-D[i-1]);
int a=getpre(1,n,1,B);
if(a<n) printf("%lld\n",updata(1,n,1,a+1,n,B));
else printf("0\n");
}
return 0;
}//4 4 1 2 4 3 1 1 2 2 3 0 4 4

【BZOJ4293】[PA2015]Siano 线段树的更多相关文章

  1. BZOJ4293 [PA2015]Siano(线段树)

    传送门 这Seg确实不好写,不过因为它与ai的相对顺序无关,所以,我们在对ai排序之后,就可做了.维护一个区间最大值,维护一个和,维护一个区间赋值的懒标记,再维护一个时间变化的标记就可以了. 因为不论 ...

  2. BZOJ.4293.[PA2015]Siano(线段树)

    题目链接 \(Description\) 有一片n亩的土地,要在这上面种草. 在每一亩土地上都种植了一种独一无二的草,其中,第\(i\)亩土地的草每天会长高\(a[i]\)厘米. 一共会进行\(m\) ...

  3. BZOJ4293: [PA2015]Siano

    Description 农夫Byteasar买了一片n亩的土地,他要在这上面种草. 他在每一亩土地上都种植了一种独一无二的草,其中,第i亩土地的草每天会长高a[i]厘米. Byteasar一共会进行m ...

  4. 【BZOJ】4293: [PA2015]Siano 线段树上二分

    [题意]给定n棵高度初始为0的草,每天每棵草会长高a[i],m次收割,每次在d[i]天将所有>b[i]的草收割到b[i],求每次收割量.n<=500000. [算法]线段树上二分 [题解] ...

  5. 2018.07.23[PA2015]Siano(线段树)

    [PA2015]Siano 描述 Description 农夫Byteasar买了一片n亩的土地,他要在这上面种草. 他在每一亩土地上都种植了一种独一无二的草,其中,第i亩土地的草每天会长高a[i]厘 ...

  6. [火星补锅] siano 神奇的线段树

    前言: 本来以为很难打的,没想到主干一次就打对了,然而把输入的b和d弄混了,这sb错误调了两个小时... 解析: 神奇的线段树.注意到有一个性质,无论怎么割草,生长速度快的一定不会比生长速度慢的矮.因 ...

  7. 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)

    传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...

  8. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  9. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

随机推荐

  1. MSB与LSB Big Endian Little Endian

    Most Significant Bit, Last(Least) Significant Bit 最高有效位(MSB) 指二进制中最高值的比特.在16比特的数字音频中,其第1个比特便对16bit的字 ...

  2. ARC072/ABC059

    AtCoder Regular Contest 072 / Beginner Contest 059 Announcement <br > 猛然发现今天有一场AC.....然后..显示手残 ...

  3. 扩展欧几里得算法(exGCD)学习笔记

    @(学习笔记)[扩展欧几里得] 本以为自己学过一次的知识不会那么容易忘记, 但事实证明, 两个星期后的我就已经不会做扩展欧几里得了...所以还是写一下学习笔记吧 问题概述 求解: \[ax + by ...

  4. 好用的Python IDLE Sublime Text 3推荐

    Sublime Text 3 下载地址为 LINK, Sublime Text 3 is currently in beta. The latest build is 3114. 参考的激活方式为输入 ...

  5. win10安装 迅雷

    下载安装文件所在目录 ,右键,选择以管理员身份运行,输入程序地址,如D:\download\ThunderMini_dl1.5.3.288.exe,回车,这样就出来了程序安装页面,之后就可以就行正常的 ...

  6. 两点C#的propertyGrid的使用心得【转】

    源文:http://www.cnblogs.com/bicker/p/3318934.html 最近接触C#的PropertyGrid比较多,得到了两个小心得记录一下. 第1点是关于控制Propert ...

  7. SVN服务器配置说明 【转】

    http://www.cnblogs.com/ricksun/articles/1564905.html 1.前 言 花了72小时,终于把 Subversion 初步掌握了.从一个连“什么是版本控制” ...

  8. 【翻译自mos文章】检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法

    检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法 来源于: How to Check Whether Oracle Binary/In ...

  9. Cocos2d-x初识

    cocos2d-x引擎是什么 在学习游戏的时候就有意的搜索这方面的知识,知道游戏须要游戏引擎,引擎听着非常厉害,只是就是一个游戏框架. 或许某一个游戏框架火起来了,就非常流行了,只是我觉得不论什么游戏 ...

  10. Web文件的ContentType类型大全

    ".*"="application/octet-stream"".001"="application/x-001"&qu ...