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

时间:2022-09-06 15:01:08

洛谷题目传送门

一血祭

向dllxl致敬!

算是YNOI中比较清新的吧,毕竟代码只有1.25k。

首先我们对着题意模拟,寻找一些思路。

每次选了一个最大的数后,它和它周围两个数都要减一。这样无论如何,我们都选不到旁边那两个数,只有第一次选的那个数会对答案产生它的大小的贡献。

于是就可以写出一个\(O(nm\log n)\)的暴力用来对拍了

#include<bits/stdc++.h>
#define LL long long
#define R register int
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
using namespace std;
const int SZ=1<<19,N=1e5+9;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
int a[N],b[N];
bool vis[N];
inline bool Cmp(R&x,R y){
return a[x]>a[y]||(a[x]==a[y]&&x<y);
}
int main(){
R n=in();
for(R i=1;i<=n;++i)a[i]=in();
for(R q=in();q--;){
a[in()]=in();
for(R i=1;i<=n;++i)b[i]=i;
sort(b+1,b+n+1,Cmp);
memset(vis+1,0,n);
LL ans=0;
for(R i=1;i<=n;++i){
if(vis[b[i]])continue;
vis[b[i]-1]=vis[b[i]]=vis[b[i]+1]=1;
ans+=a[b[i]];
}
printf("%lld\n",ans);
}
return 0;
}

进一步观察,对于一个序列中的一个极长单调区间,我们取到了最大的、第三大的、第五大的。。。

考虑用set维护好序列的所有极值点,相邻两个极值点所包含区间的贡献就可以通过树状数组查区间和直接算(注意分奇偶)。

单点修改的时候,只会影响到自己周围至多三个的极值点状态、以及左右各至多两个区间的单调性,暴力删掉原来的贡献再加新的贡献就好了。

统计答案时细节很多,边界问题也很多,想清楚后再动手还是很舒服的。

时间复杂度\(O((n+m)\log n)\),因为数据范围不怎么卡(这一点也是YNOI极罕见的)所以蒟蒻直接牺牲常数来减少代码长度了qaq

#include<bits/stdc++.h>
#define LL long long
#define I inline
#define R register int
#define G if(++ip==ie)if(fread(ip=buf,1,SZ,stdin))
using namespace std;
typedef set<int>::iterator IT;
const int SZ=1<<19,N=1e5+9;
char buf[SZ],*ie=buf+SZ,*ip=ie-1;
inline int in(){
G;while(*ip<'-')G;
R x=*ip&15;G;
while(*ip>'-'){x*=10;x+=*ip&15;G;}
return x;
}
int n,a[N];LL ans;set<int>s;
struct BIT{
LL a[N];
I void Upd(R i,R v){
for(;i<N;i+=i&-i)a[i]+=v;
}
I void Qry(R l,R r,LL v){
for(R i=r;i;i-=i&-i)v+=a[i];
for(R i=l;i;i-=i&-i)v-=a[i];
}
}b[2];
#define ODD(O) ((*l^*O(j=l))&1)
I void Calc(IT l,IT r,R op){
IT i,j;LL sum=*l&&a[*l+1]>a[*l]&&!ODD(--)&&!ODD(++)?a[*l]:0;
for(i=l++;i!=r;i=l++)
if(a[*l]>a[*i])b[*l&1].Qry(*i,*l,sum);
else b[*i&1].Qry(*i,*l-ODD(++),sum);
ans+=sum*op;
}
I void Chk(R x){
if((a[x]>a[x-1])!=(a[x+1]>a[x]))s.insert(x);
else s.erase(x);
}
I void Upd(R x){
R y=in();
IT i=s.lower_bound(x),l=i,r=i;
--l;if(l!=s.begin())--l;
++r;if(r==s.end()||(*i==x&&++r==s.end()))--r;
Calc(l,r,-1);
b[x&1].Upd(x,y-a[x]);a[x]=y;
Chk(x);if(x>1)Chk(x-1);if(x<n)Chk(x+1);
Calc(l,r,1);
}
int main(){
n=in();s.insert(0);s.insert(n+1);
for(R i=1;i<=n;++i)Upd(i);
for(R q=in();q;--q)Upd(in()),printf("%lld\n",ans);
return 0;
}

洛谷P5069 [Ynoi2015]纵使日薄西山(树状数组,set)的更多相关文章

  1. &lbrack;洛谷P1198&sol;BZOJ1012&rsqb;&lbrack;JSOI2008&rsqb; 最大数 - 树状数组&sol;线段树&quest;

    其实已经学了树状数组和线段树,然而懒得做题,所以至今没写多少博客 Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数 ...

  2. 洛谷P3688&sol;uoj&num;291&period; &lbrack;ZJOI2017&rsqb;树状数组

    传送门(uoj) 传送门(洛谷) 这里是题解以及我的卡常数历程 话说后面那几组数据莫不是lxl出的这么毒 首先不难发现这个东西把查询前缀和变成了查询后缀和,结果就是查了\([l-1,r-1]\)的区间 ...

  3. 洛谷P3368 【模板】树状数组 2

    P3368 [模板]树状数组 2 102通过 206提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 暂时没有讨论 题目描述 如题,已知一个数列,你需要进行下面两 ...

  4. 洛谷P3374 【模板】树状数组 1

    P3374 [模板]树状数组 1 140通过 232提交 题目提供者HansBug 标签 难度普及/提高- 提交  讨论  题解 最新讨论 题目描述有误 题目描述 如题,已知一个数列,你需要进行下面两 ...

  5. 洛谷 P3368 【模板】树状数组 2

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  6. 洛谷 P3374 【模板】树状数组 1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  7. 树状数组模板(pascal) 洛谷P3374 【模板】树状数组1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  8. 洛谷 P3368 【模板】树状数组 2&lpar;区间修改点查询&rpar;

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的值 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  9. 洛谷 P3368 【模板】树状数组 2 题解

    P3368 [模板]树状数组 2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的值 输入格式 第一行包含两个整数N.M,分别表示该数列数字的个 ...

随机推荐

  1. HTTPS学习总结

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px Verdana; color: #393939 } span.s1 { } HTTPS学习总结 ...

  2. 【HTML5】audio音频

    当前,audio 元素支持三种音频格式:   IE 9 Firefox 3.5 Opera 10.5 Chrome 3.0 Safari 3.0 Ogg Vorbis   √ √ √   MP3 √ ...

  3. LINUX 产生PPM 驱动例子

    APP: //author:DriverMonkey //phone:13410905075 //mail:bookworepeng@Hotmail.com //qq:196568501 #inclu ...

  4. codeforces 685B Kay and Snowflake 树的重心

    分析:就是找到以每个节点为根节点的树的重心 树的重心可以看这三篇文章: 1:http://wenku.baidu.com/link?url=yc-3QD55hbCaRYEGsF2fPpXYg-iO63 ...

  5. UVA 10585 Center of symmetry

    题意:给出一个点集,问这个集合有没有中心点使点集对称,这个点可以是点集中的点也可以不是点集的点. 解法:一开始我枚举每两个点连线的中点……结果T了orz当时也不知道怎么想的…… 将点按横坐标排序,如果 ...

  6. 2015北京网络赛 A题 The Cats&&num;39&semi; Feeding Spots 暴力

    The Cats' Feeding Spots Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/acm ...

  7. Android 快速选择联系人

    Activity 代码如下: /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache ...

  8. window下nginx的常用命令

    window nginx 启动 常用命令 2016-05-04 11:11 214人阅读 评论(0) 收藏 举报 分类: nginx(5) 版权声明:本文为博主原创文章,未经博主允许不得转载. 启动 ...

  9. python打造一个Mysql数字类型注入脚本&lpar;1&rpar;

    前言: 总是想写一个sql注入脚本,但是之前的那些都不行. 这次做好了准备,然后嘿嘿嘿. 准备: sql注入的基础知识 熟悉怎么判断 正文: 思路概念图: 这里我没有限制用户输入,不限制的话可能会 @ ...

  10. 1&period;1python解决数学建模之席位分配问题

    一:上代码 #比例法def rate_method(p,n):    lst =[] #保存各组席位数    sum_ =sum(p)    #人数和    k =0#临时变量    for i in ...