3973: seq

题目描述

小y 的男朋友送给小y 一个数列{ai}{ai},并且刁难小y 要她维护这个序列。

具体而言,小y 的男朋友要求小y 完成两个操作:

1. 修改数列中的一个数

2. 设pipi表示maxij=1ajmaxj=1iaj,求出n∑i=1pi∑i=1npi。

小y 不会做,于是向你求助。

输入

第一行一个数nn表示数列长度。

第二行nn个由空格隔开的数表示数列aa。

第三行一个数mm表示修改数。

接下来mm行,每行两个数pos,valuepos,value,表示把aposapos改成valuevalue。

输出

mm行,每行一个数,表示对于每次修改后的n∑i=1pi∑i=1npi。

样例输入

<span style="color:#333333"><span style="color:#333333">10
114 357 904 407 100 624 449 897 115 846
20
5 357
6 350
2 939
9 1182
7 1062
2 3300
4 6867
4 2076
3 8458
9 6575
10 5737
10 338
9 10446
4 7615
2 5686
4 10091
1 6466
6 15551
3 10914
7 3234</span></span>

样例输出

<span style="color:#333333"><span style="color:#333333">7703
7703
8565
9051
9297
29814
54783
29814
71078
71078
71078
71078
75054
75054
77440
85605
92737
119327
123429
123429</span></span>

提示

对于前30%30%的数据,n,m≤5000n,m≤5000;

对于前60%60%的数据,n,m≤50000n,m≤50000;

对于100%100%的数据,n≤3×105,ai≤109n≤3×105,ai≤109。

来源

2018年10月hnsdfz集训


solution

传说中的套路题,可是我不会

理解了好久

首先最终每个数的答案一定是递增的,也就是每个数会被之前的某个数“盖住”

我们用线段树维护l~r的答案和最大值

这里的答案只考虑l~r,不受其他影响

那么修改很好实现,主要是怎么维护区间

分类

1.tree[k*2].max>=tree[k*2+1].max

也就是左边完全盖住了右边

那答案就是tree[k*2].max*tree[k*2+1].len+tree[k*2].sum

2.tree[k*2].max<tree[k*2+1].max

左边盖住右边的一小部分

再分类,设M为tree[k*2].max,ls为右儿子的左儿子,rs为右儿子的右儿子

(1)M<tree[ls].max

那么rs的答案是正确的,而左儿子未知

所以递归算左儿子,右儿子用减的

(2)M>tree[ls].max

左儿子被完全盖住,右儿子递归算

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
#define maxn 300005
using namespace std;
int n,m,a[maxn],p,val;
struct node{
int l,r,len;ll Max,sum;
}tree[maxn*4];
ll pushup(int k,ll v){
if(v>tree[k].Max)return tree[k].len*v;
if(tree[k].l==tree[k].r)return max(tree[k].Max,v);
if(tree[k*2].Max>v){
return pushup(k*2,v)+tree[k].sum-tree[k*2].sum;
}//right remain
if(tree[k*2].Max<=v){
return tree[k*2].len*v+pushup(k*2+1,v);
}//left covered
}
void wh(int k){
tree[k].Max=max(tree[k*2].Max,tree[k*2+1].Max);
tree[k].sum=tree[k*2].sum+pushup(k*2+1,tree[k*2].Max);
}
void build(int k,int L,int R){
tree[k].l=L;tree[k].r=R;tree[k].len=R-L+1;
if(L==R){
tree[k].Max=tree[k].sum=a[L];return;
}
int mid=L+R>>1;
build(k*2,L,mid);build(k*2+1,mid+1,R);
wh(k);
}
void change(int k){
if(tree[k].l==tree[k].r){
tree[k].sum=tree[k].Max=val;
return ;
}
int mid=tree[k].l+tree[k].r>>1;
if(p<=mid)change(k*2);
else change(k*2+1);
wh(k);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build(1,1,n);
cin>>m;
for(int i=1;i<=m;i++){
scanf("%d%d",&p,&val);
change(1);
printf("%lld\n",tree[1].sum);
}
return 0;
}

3973: seq的更多相关文章

  1. BZOJ1798: [Ahoi2009]Seq 维护序列seq[线段树]

    1798: [Ahoi2009]Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 5504  Solved: 1937[Submit ...

  2. Linux 设备驱动程序 proc seq

    不能再简化 #include<linux/module.h> #include<linux/init.h> #include<linux/seq_file.h> # ...

  3. seq

    Linux 中seq 命令的用法 用于产生从某个数到另外一个数之间的所有整数 用法: seq [选项]... 尾数 或:seq [选项]... 首数 尾数 或:seq [选项]... 首数 增量 尾数 ...

  4. 20 seq 某个数到另外一个数之间的所有整数

    seq命令Shell内建命令 seq命令用于产生从某个数到另外一个数之间的所有整数. 语法 : seq [选项]... 尾数 seq [选项]... 首数 尾数 seq [选项]... 首数 增量 尾 ...

  5. 【双标记线段树】bzoj1798维护序列seq

    一.题目 描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中的一段数全部乘一个值; (2)把数列 ...

  6. seq 显示00 01的格式

    for i in `seq -w 00 20` ; do echo $i ;done 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 ...

  7. RNA seq 两种计算基因表达量方法

    两种RNA seq的基因表达量计算方法: 1. RPKM:http://www.plob.org/2011/10/24/294.html 2. RSEM:这个是TCGAdata中使用的.RSEM据说比 ...

  8. Linux常用命令之seq

    标题:seq命令的使用 作用:seq命令用于以指定增量从首数开始打印数字到尾数,即产生从某个数到另外一个数之间的所有整数,并且可以对整数的格式.宽度.分割符号进行控制 语法: [1] seq [选项] ...

  9. CDOJ 1157 数列(seq) 分块+线段树

    数列(seq) Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1157 Desc ...

随机推荐

  1. Matlab 中实用数据结构之 containers.Map

    概要   熟悉 Python 的都知道字典 Dict 类型数据结构功能的强大,Matlab 中虽然有表结构,但是其列名必须是亦变量名类型的字符串,如果我想用数字开头的字符串作键值,其表结构就无能为力了 ...

  2. Java面向对象之继承,方法重写,super关键字,员工类系列继承题

    在程序中,如果想声明一个类继承另一个类,需要使用extends关键字. 格式: class 子类 extends 父类 {} 继承的好处 1.继承的出现提高了代码的复用性,提高软件开发效率. 2.继承 ...

  3. IBM MQ Explore使用

    一,版本说明: 系统:win10.MQ:V9.04 二.关于帮助文档: 1.读了差不多一大半,个人感觉说明的比较生僻,应该是直译过来的.但是还是可以从这里面学一下基本的操作. 2.对于一些基本的操作, ...

  4. 32-2题:LeetCode102. Binary Tree Level Order Traversal二叉树层次遍历/分行从上到下打印二叉树

    题目 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 ...

  5. 正则表达式-基础知识Review

    正则表达式(Regular Expression)是计算机科学的一个概念. 正则表达式使用单个字符窜来描述.匹配一系列符合某个句法规则的字符窜. 在很多文本编辑器里, 正则表达式通常用来被检索替换哪些 ...

  6. MySQL 如何生成日期表

    MySQL 如何生成日期表 在开发过程中,经常会遇到统计问题,通常交易信息都不是连续的,此时,统计出来的数据都是不连续的,所以提前生成一个时期表,当没有交易数据的时候填充0,就可以了,下面是生成日期表 ...

  7. MySQL批量插入大量数据方法

    在MySQL数据库中,如果要插入上百万级的记录,用普通的insert into来操作非常不现实,速度慢人力成本高,推荐使用Load Data或存储过程来导入数据,我总结了一些方法分享如下,主要基于My ...

  8. Android Studio 安装与使用ADB wifi 无线调试

    首先,安装ADB WIFI File->Settings->Plugins 其次,用USB连接手机与电脑(并开启手机的调试模式) 任务栏若无提示,即可拔下USB线,开始无线调试 任务栏若是 ...

  9. ubuntu crontab设置定时任务

    ubuntu 设置定时任务   crontab -l  #查看详情crontab -e #设置定时任务 * * * * * command 分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用* ...

  10. 动态规划:HDU1224-Free DIY Tour

       Free DIY Tour Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...