[Ynoi2015]纵使日薄西山

题目大意:

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

定义一次操作为,选择一个位置$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);else
				return 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);else
				return 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);else
			ret+=even.ask(*it-1)-even.ask(*pre-1);
		if(*nxt&1)ret+=odd.ask(*nxt-1)-odd.ask(*it);else
			ret+=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);else
			even.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);else
				if(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

表格数据本质上是由行和列组成的二维数据结构,通常可以表示为一组对象(Object),每个对象对应一行,对象中的键(Key)对应表格的列名,值(Value)则表示该列对应的数据。 ### JSON 表示表格数据的结构 1. **基本结构** JSON 使用数组(Array)来表示多行数据,数组中的每个元素是一个对象,对象中包含键值对。例如,一个包含姓名、性别和年龄的表格数据可以表示为: ```json [ { "stu_name": "日薄西山", "stu_sex": "1", "stu_age": "24" }, { "stu_name": "凯楠印象", "stu_sex": "1", "stu_age": "25" }, { "stu_name": "陈安", "stu_sex": "1", "stu_age": "25" } ] ``` 这种结构清晰地表示了表格的每一行数据,并且可以通过键名直接访问对应列的数据[^3]。 2. **嵌套结构** 如果表格数据包含复杂的嵌套信息,例如某列中包含另一个对象或数组,也可以通过嵌套对象或数组实现。例如,一个包含地址信息的表格数据可以表示为: ```json [ { "stu_name": "日薄西山", "stu_sex": "1", "stu_age": "24", "address": { "city": "北京", "district": "朝阳区" } }, { "stu_name": "凯楠印象", "stu_sex": "1", "stu_age": "25", "address": { "city": "上海", "district": "浦东新区" } } ] ``` 这种方式可以表示更加复杂的表格数据结构,同时保持数据的可读性和可解析性。 3. **表头与数据分离的结构** 如果需要将表格的列名(表头)与数据分离存储,可以使用对象包含两个部分:`headers` 表示列名,`rows` 表示数据行。例如: ```json { "headers": ["姓名", "性别", "年龄"], "rows": [ ["日薄西山", "男", "24"], ["凯楠印象", "男", "25"], ["陈安", "男", "25"] ] } ``` 这种结构适合在数据展示时需要动态处理表头的场景,例如前端渲染表格时。 ### 数据解析与展示 在不同编程语言中,可以通过相应的 JSON 解析库读取并操作上述结构的数据。例如,在 Java 中可以使用 `JSON.parseArray` 方法将 JSON 数据转换为对象列表;在 Python 中则可以使用内置的 `json` 模块进行解析和操作;在 Jupyter Notebook 中,还可以借助 `tabulate` 库将 JSON 数据以表格形式输出,提升可读性[^2]。 ### 示例代码(Python) 以下是一个使用 Python 解析并打印 JSON 表格数据的示例: ```python import json from tabulate import tabulate # JSON 格式的表格数据 json_data = ''' [ {"姓名": "日薄西山", "性别": "男", "年龄": "24"}, {"姓名": "凯楠印象", "性别": "男", "年龄": "25"}, {"姓名": "陈安", "性别": "男", "年龄": "25"} ] ''' # 解析 JSON 数据 data = json.loads(json_data) # 使用 tabulate 将数据以表格形式输出 print(tabulate(data, headers="keys", tablefmt="psql")) ``` 运行结果将是一个美观的表格输出,适合在终端或 Jupyter Notebook 中查看。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值