【线段树】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem H. Hay
有一些草,一开始高度都是0,它们的生长速率不同。
给你一些单增的日期,在这些日期要将>b的草的部分都割掉,问你每次割掉的部分有多少。
将草的生长速率从大到小排序,这样每次割掉的是一个后缀,而且不会影响它们生长速率的递增性。
就是三种操作,一种对一个后缀赋值,一种对整个数组作 + 另一个数组(d(i)-d(i-1))*a,一种求区间和。
可以通过打标记的线段树实现,标记下放通过预处理生长速率数组的前缀和可以实现。
队友的代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <map>
#include <cstring>
#include <vector>
#include <ctime>
using namespace std; struct nod{
int l,r,ls,rs;
long long sum,ma,lazyd,lazyge;
}t[2000010];
int num[500010],n,m,i,p,now;
long long ans,pre,sum[500010],d,b;
char c;
void ge(int d,long long a)
{
t[d].lazyd=0;
t[d].lazyge=a;
t[d].sum=(t[d].r-t[d].l+1)*a;
t[d].ma=a;
} void addday(int d,long long a)
{
t[d].lazyd+=a;
t[d].sum+=(sum[t[d].r]-sum[t[d].l-1])*a;
t[d].ma+=num[t[d].r]*a;
} void lazy(int d)
{
int ls=t[d].ls,rs=t[d].rs;
if (t[d].lazyge!=-1)
{
ge(ls,t[d].lazyge);
ge(rs,t[d].lazyge);
t[d].lazyge=-1;
}
if (t[d].lazyd!=0)
{
addday(ls,t[d].lazyd);
addday(rs,t[d].lazyd);
t[d].lazyd=0;
} } int buildtree(int l,int r)
{
int k,mid;
k=++p;
t[k].l=l;
t[k].r=r;
t[k].lazyge=-1;
if (l==r) return k;
mid=(l+r)/2;
t[k].ls=buildtree(l,mid);
t[k].rs=buildtree(mid+1,r);
return k;
} int find(int d,long long a)
{
if (t[d].l==t[d].r) return t[d].l;
lazy(d);
if (t[t[d].ls].ma>a) return find(t[d].ls,a);
return find(t[d].rs,a);
} long long getsum(int d,int l,int r)
{
int mid;
if (l<=t[d].l && r>=t[d].r) return t[d].sum;
mid=(t[d].l+t[d].r)/2;
lazy(d);
if (r<=mid) return getsum(t[d].ls,l,r);
if (l>mid) return getsum(t[d].rs,l,r);
return getsum(t[d].ls,l,mid)+getsum(t[d].rs,mid+1,r);
} void modify(int d,int l,int r,long long a)
{
int mid;
if (l<=t[d].l && r>=t[d].r)
{
ge(d,a);
return;
}
lazy(d);
mid=(t[d].l+t[d].r)/2;
if (l>mid) modify(t[d].rs,l,r,a);
if (r<=mid) modify(t[d].ls,l,r,a);
if (l<=mid && r>mid)
{
modify(t[d].ls,l,mid,a);
modify(t[d].rs,mid+1,r,a);
}
t[d].ma=max(t[t[d].ls].ma,t[t[d].rs].ma);
t[d].sum=(t[t[d].ls].sum+t[t[d].rs].sum);
} long long read()
{
c=getchar(); ans=0;
while (c<'0' || c>'9') c=getchar();
while (c>='0' && c<='9')
{
ans=ans*10+c-48;
c=getchar();
}
return ans;
} int main()
{
//freopen("ac.in","r",stdin);
//freopen("ac.out","w",stdout);
scanf("%d%d",&n,&m);
buildtree(1,n);
for (i=1;i<=n;i++) num[i]=read();
sort(num+1,num+n+1);
for (i=1;i<=n;i++) sum[i]=sum[i-1]+num[i];
for (i=1;i<=m;i++)
{
d=read(); b=read();
addday(1,d-pre);
if (t[1].ma<=b)
{
pre=d;
printf("0\n");
continue;
}
now=find(1,b);
printf("%lld\n",getsum(1,now,n)-b*(n-now+1));
modify(1,now,n,b);
pre=d;
}
}
【线段树】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem H. Hay的更多相关文章
- 【计算几何】【极角排序】【二分】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem J. Triangles
平面上给你n(不超过2000)个点,问你能构成多少个面积在[A,B]之间的Rt三角形. 枚举每个点作为直角顶点,对其他点极角排序,同方向的按长度排序,然后依次枚举每个向量,与其对应的另一条直角边是单调 ...
- 【枚举】Petrozavodsk Summer Training Camp 2016 Day 6: Warsaw U Contest, XVI Open Cup Onsite, Sunday, August 28, 2016 Problem G. Equation
f(n)定义为n的十进制表示下所有位的平方和. 问你方程K*f(n)=n在a<=n<=b中的解的个数. 发现f(n)最大不超过2000,可以直接枚举f(n),然后判断K*f(n)的位的平方 ...
- Petrozavodsk Summer-2016. Warsaw U Contest, XVI Open Cup Onsite.
Petrozavodsk Summer-2016. Warsaw U Contest, XVI Open Cup Onsite. Problem A. Gambling Problem B. Colo ...
- 【取对数】【哈希】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem J. Bobby Tables
题意:给你一个大整数X的素因子分解形式,每个因子不超过m.问你能否找到两个数n,k,k<=n<=m,使得C(n,k)=X. 不妨取对数,把乘法转换成加法.枚举n,然后去找最大的k(< ...
- 【BFS】【最小生成树】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem G. We Need More Managers!
题意:给你n个点,点带权,任意两点之间的边权是它们的点权的异或值中“1”的个数,问你该图的最小生成树. 看似是个完全图,实际上有很多边是废的.类似……卡诺图的思想?从读入的点出发BFS,每次只到改变它 ...
- 【状压dp】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem E. Guessing Game
题意:给你n个两两不同的零一串,Alice在其中选定一个,Bob去猜,每次询问某一位是0 or 1.问你最坏情况下最少要猜几次. f(22...2)表示当前状态的最小步数,2表示这位没确定,1表示确定 ...
- 【推导】【单调性】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem B. Tribute
题意:有n个数,除了空集外,它们会形成2^n-1个子集,给你这些子集的和的结果,让你还原原来的n个数. 假设原数是3 5 16, 那么它们形成3 5 8 16 19 21 24, 那么第一轮取出开头的 ...
- 【线性基】Petrozavodsk Winter Training Camp 2018 Day 1: Jagiellonian U Contest, Tuesday, January 30, 2018 Problem A. XOR
题意:给你一些数,问你是否能够将它们划分成两个集合,使得这两个集合的异或和之差的绝对值最小. 设所有数的异或和为S,集合A的异或和为A. 首先,S的0的位对答案不造成影响. S的最高位1,所对应的A的 ...
- 【推导】【构造】Petrozavodsk Summer Training Camp 2015 Day 2: Xudyh (TooSimple) Contest, Saturday, August 22, 2015 Problem G. Travelling Salesman Problem
一个矩阵,每个位置有一个非负整数,一个人从左上走到右下,不能走重复的格子,问得到的最大权值. 当长宽不都为偶数时,必然能走遍所有格子,横着从左到右,从右到左(或是竖着走)走完即可. 当长宽都是偶数时, ...
随机推荐
- [bzoj1002]轮状病毒-矩阵树定理
Brief Description 求外圈有\(n\)个点的, 形态如图所示的无向图的生成树个数. Algorithm Design \[f(n) = (3*f(n-1)-f(n-2)+2)\] Co ...
- bzoj 1483 链表启发式合并
首先我们可以比较容易的在n的时间内算出来开始的答案,我们维护一些链表,分别表示不同的颜色,那么我们在计算答案的时候,只需要扫一遍所有的链表,判断链表相邻两项是否在序列中相邻,不相邻的话肯定在这其中的一 ...
- Lucene7.2.1系列(一)快速入门
系列文章: Lucene系列(一)快速入门 Lucene系列(二)luke使用及索引文档的基本操作 Lucene系列(三)查询及高亮 Lucene是什么? Lucene在维基百科的定义 Lucene是 ...
- php中的__call()函数重载
<?php #调用类中没有的方法时, 会自动调用__call方法重载 #第一个参数是调用时的方法名, 第二个参数为参数组成的数组 class Cat{ public function Hello ...
- Django【进阶】数据库查询性能相关
之前项目中没有考虑过数据库查询关于效率的问题,如果请求量大,数据庞大,不考虑性能的话肯定不行. tips:如图之前我们遇到过,当添加一张表时,作为原来表的外键,要给个默认值,现在我们写null ...
- python基础===PEP网站,代码规范指南
PEP 8是最古老的PEP之一,它向Python程序员提供了代码格式设置指南.PEP 8的篇幅很长,但大都与复杂的编码结构相关. https://python.org/dev/peps/pep-000 ...
- python基础===如何优雅的写代码(转自网络)
本文是Raymond Hettinger在2013年美国PyCon演讲的笔记(视频, 幻灯片). 示例代码和引用的语录都来自Raymond的演讲.这是我按我的理解整理出来的,希望你们理解起来跟我一样顺 ...
- nodejs 使用redis 管理session
一.在开发机安装redis并远程连接 因本人的远程开发机配置原因,使用jumbo安装redis 首先登录开发机,并使用jumbo 安装redis:jumbo install redis 查看redis ...
- SVN服务的配置与管理
引言 没当服务器重启,SVN服务都会停止,每次都得重启一下服务,为了解决这样的问题.有了下文. 一.配置自启动服务 sc create SVNService binpath="E:\svn\ ...
- 【python】资料记录
今天看了一些关于python的知识: 1.装饰器:https://www.zhihu.com/question/25950466/answer/31731502 2.*args的用法:http://b ...