题目大意:

给定一个序列,每次单点修改,然后进行询问。

定义一次操作为,选择一个位置$x$,将这个位置的数和左边、右边两个位置的数(不存在则忽略)各减去1,然后和0取max。

对序列中最大的位置进行一次操作(相同则取最前面的),不断重复,直到所有位置为0为止。

问执行了多少次操作。

询问互相独立(即下一次询问的序列并不是全0)。

解题思路:

在太阳西斜的这个世界里,置身天上之森。等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去、逐渐消逝的未来。我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘。————世界上最幸福的女孩

我的愿望是,和珂朵莉一样可爱。


淦不动辣QaQ就窝一个在那瞎分块

一开始的做法是先分块,求出块内的答案,然后瞎分类讨论(自闭了QAQ)。

实际上这个性质挺优美的为啥窝就是发现不了啊

显然一次对某个位置操作到底,和答案是一样的(当你选择这个数进行操作后,其左边和右边就永远不会被操作。而其他数对这个位置无影响)。

所以相当于求所有会被操作的位置上的数的和。

考虑一个单调递增或单调递减的序列,在这上面选的数一定是一个选一个不选(奇偶性相同)。

所以我们对奇数、偶数位置分别用树状数组维护一下,然后用set记录序列的极大、极小值的位置。则可以快速计算出两个极值之间的区间的贡献。

然后对于单点修改,对受到影响的部分区间重新计算贡献即可。

细节挺多的,比如对极小值是否取到的考虑(仅当其左右两个极大值的位置的奇偶性和这个极小值位置相同时,才能取到这个值)。

时间复杂度$O(n\log n)$。

C++ Code:

#include<cstdio>
#include<set>
const int N=1e5+6;
typedef long long LL;
int n,a[N];
struct BIT{LL b[N];inline void add(int i,int x){for(;i<N;i+=i&-i)b[i]+=x;}inline LL ask(int i){LL x=0;for(;i;i^=i&-i)x+=b[i];return x;}
}odd,even;
std::set<int>s;
LL ans=0;
LL get(int x){if(x<1||x>n)return 0;auto it=s.find(x);if(*it==1){auto nxt=it;++nxt;if(a[*it]<a[*nxt]){if(*nxt&1)return odd.ask(*nxt-1)-odd.ask(*it-1);elsereturn even.ask(*nxt-1)-even.ask(*it-1);}else return 0;}if(*it==n){auto pre=it;--pre;if(a[*pre]>=a[*it]){if(*pre&1)return odd.ask(*it)-odd.ask(*pre-1);elsereturn even.ask(*it)-even.ask(*pre-1);}else return a[n];}auto pre=it,nxt=it;--pre,++nxt;if(a[*pre]>=a[*it]&&a[*it]<a[*nxt]){LL ret=0;if(*pre&1)ret+=odd.ask(*it-1)-odd.ask(*pre-1);elseret+=even.ask(*it-1)-even.ask(*pre-1);if(*nxt&1)ret+=odd.ask(*nxt-1)-odd.ask(*it);elseret+=even.ask(*nxt-1)-even.ask(*it);if((*pre&1)==(*it&1)&&(*nxt&1)==(*it&1))ret+=a[*it];return ret;}else return 0;
}
int main(){scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%d",a+i),((i&1)?odd:even).add(i,a[i]);s.insert(-2),s.insert(-1),s.insert(n+2),s.insert(n+3);s.insert(1);for(int i=2;i<n;++i)if(a[i-1]<a[i]&&a[i]>=a[i+1]||a[i-1]>=a[i]&&a[i]<a[i+1])s.insert(i);s.insert(n);for(int i:s)ans+=get(i);int q;for(scanf("%d",&q);q--;){int x,y;scanf("%d%d",&x,&y);int nxt=*s.upper_bound(x),pre=*--s.lower_bound(x);ans-=get(nxt),ans-=get(pre);nxt=*s.upper_bound(nxt),pre=*--s.lower_bound(pre);ans-=get(nxt),ans-=get(pre);if(s.count(x))ans-=get(x),s.erase(x);s.erase(x-1),s.erase(x+1);if(x&1)odd.add(x,-a[x]),odd.add(x,y);elseeven.add(x,-a[x]),even.add(x,y);a[x]=y; for(int i=x-1;i<=x+1;++i){if(i<1||i>n)continue;if(i==1||i==n)s.insert(i);elseif(a[i-1]<a[i]&&a[i]>=a[i+1]||a[i-1]>=a[i]&&a[i]<a[i+1])s.insert(i);}for(auto l=s.find(pre),r=s.upper_bound(nxt);l!=r;++l)ans+=get(*l);printf("%lld\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/Mrsrz/p/10602966.html

[Ynoi2015]纵使日薄西山相关推荐

  1. (Ynoi2015) 纵使日薄西山 题解

    一道耗费大量精力的数据结构题目 题目链接 原题目 题目分析 大家应该都能意识到,每一次都去找下标最小的最大值是非常浪费时间的.而对于一个位置而言,只要被操作一次就等于这个位置要被操作a[i]次,因为两 ...

  2. 【树状数组】【P5069】[Ynoi2015]纵使日薄西山

    Description 给定一个长度为 \(n\) 的非负整数序列 \(\{a_n\}\),\(q\) 次操作,每次要么单点修改序列某个值,要么查询整个序列需要操作多少次才能变成全 \(0\). 一次 ...

  3. 洛谷P5069 [Ynoi2015]纵使日薄西山(树状数组,set)

    洛谷题目传送门 一血祭 向dllxl致敬! 算是YNOI中比较清新的吧,毕竟代码只有1.25k. 首先我们对着题意模拟,寻找一些思路. 每次选了一个最大的数后,它和它周围两个数都要减一.这样无论如何, ...

  4. Luogu P5069 [Ynoi2015] 纵使日薄西山

    一开始想用线段树维护, 然后发现太多细节了,QAQ. 我们 可以发现一个数可以被取到最大值, 那么直接把他删到0不会影响结果. 因为 两边的位置都不能能取到最大值并影响当前位置. 所以我们只需要知道有 ...

  5. 洛谷P5071 [YNOI2015]此时此刻的光辉 莫队+玄学优化+卡常QWQ

    题目链接:传送门 在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此 ...

  6. 洛谷P5072 [YNOI2015]盼君勿忘 莫队+unordered_set+毒瘤卡常

    在太阳西斜的这个世界里,置身天上之森.等这场战争结束之后,不归之人与望眼欲穿的众人, 人人本着正义之名,长存不灭的过去.逐渐消逝的未来.我回来了,纵使日薄西山,即便看不到未来,此时此刻的光辉,盼君勿忘 ...

  7. [Ynoi2015]即便看不到未来

    题目大意: 给定一个序列,每次询问,给出一个区间$[l,r]$. 设将区间内的元素去重后重排的数组为$p$,求$p$中长度为$1\sim 10$的极长值域连续段个数. 长度为$L$的极长值域连续段的定 ...

  8. 曾风靡全球的 Delphi,要日薄西山了?

    (给程序员的那些事加星标) 原创:程序员的那些事 (ID:iProgrammer) 参考:TIOBE.维基百科 TIOBE 官网近日公布了 3 月编程指数信息.本月前三的编程语言是 Java.C 和 ...

  9. 《UML正日薄西山的13个理由》读后感

    原文链接:http://littletutorials.com/2008/05/15/13-reasons-for-umls-descent-into-darkness/ 中文版本:http://ne ...

最新文章

  1. 架构漫谈:我心中的架构
  2. nginx 网站目录重写
  3. 80C51单片机的最小系统
  4. Redis常用命令之操作Set(集合)
  5. Windows 10下,anaconda (conda) 虚拟环境的创建,jupyter notebook如何使用虚拟环境
  6. python3读取文件夹-python3获取文件及文件夹大小
  7. python的序列类型及其特点_Fluent Python 笔记——序列类型及其丰富的操作
  8. linux输入qsub显示错误,linux – 使用qsub运行shellscript的’意外的文件结束’和’错误导入功能定义’错误...
  9. ubuntu12.04 android studio 安装
  10. SpringBoot使用ELK日志收集
  11. 三行代码隐藏所有console.log
  12. Storm实验 -- 单词计数4
  13. python有什么用-python有什么用处?
  14. 基于java的小型超市管理系统系统(含源文件)
  15. JDK中的BitMap实现之BitSet源码分析
  16. 觅伊、Soul,这些社交软件是怎么火起来的?
  17. Windows10服务优化
  18. 企业批量寄件快递教程
  19. RTSP协议网络摄像头互联网无插件直播EasyNVR+EasyNVS,如何保持配置地址一致?
  20. 两种解读,生活的意义和方法

热门文章

  1. c语言符号运算优先级6,c语言运算符号的优先级
  2. SAP中寄售补货的两种方法分析
  3. 数学之美!~(02)十位伟大的数学家!
  4. 数据可视化工具之--百度图说
  5. 6-5 计算天数[2] (15 分)
  6. Java找图 (截屏找图 大图找小图)--自己实现“按键精灵”
  7. 2012过年的时间 2012过年放假时间 2012年什么时间过年 2012过年 2012年什么时候过年
  8. 百度地图获取本地搜索(LocalSearch)全部结果并显示标注
  9. 计算机工程本科旧金山找工,2020年旧金山大学本科热门专业
  10. php 命格算法,命格是怎么个算法???