【未知来源】等差数列

等差数列

描述

Geobiyye 是一个喜欢数据结构的女孩子。

Geobiyye 给了你一个长度为 \(n\) 的序列 \(a_i\) ,序列中每个元素的初始值为 \(0\)

接下来她会对这个序列进行 \(m\) 次操作,每次操作有 4 个参数 \(l, r, s, e\) ,表示将区间 \([l, r]\) 加上一个首项为 \(s\) ,末项为 \(e\) 的等差数列。

若一次操作中 \(l = 1, r = 5, s = 2, e = 10\) , 则对序列中第 \(1~5\) 个数分别加上 \(2,4,6,8,10\)

现在 Geobiyye 要求你求出 \(m\) 次操作后序列中的每个数的值。

输入

第一行 \(2\) 个整数 \(n, m\) ,表示序列长度和操作数。

接下来 \(m\) 行,每行 \(4\) 个整数 \(l, r, s, e\) ,含义见题目描述。数据保证等差数列中的每一项都是整数。

输出

由于输出数据过大,Geobiyye 只想要知道最终序列每一项的异或和

数据范围

对于 100%的数据: \(n,m≤500000, 1≤l<r≤n\)

题解

恼,现在我连普及组题都只能打个暴力了

看到 \(500000\) 就知道其实和数据结构没啥关系

然后中途没有询问,只问完整的,可以用差分

因为如果只有一层的前缀和的话差分依旧需要每个点都搞一次,所以我们考虑两层的前缀和

\(d\) 表示公差,则我们希望第二层的前缀和是这样的:\(s,s+d,s+2d,...,e,0,0\)

那么第一层的前缀和可以是这样的:\(s,d,d,...,d,-e,0\)

于是,我们构造出来原本的差分数组:

\(s,d-s,0,...,0,-d-e,e\)

这样构造完,代码就很简洁了:

#include<bits/stdc++.h>
using namespace std;
#define int long long 
int n,m;
int a[500010];
int pre[500010],pre2[500010];
signed main(){
	scanf("%lld%lld",&n,&m);
	for(int i=1;i<=m;++i){
		int l,r,s,e;
		scanf("%lld%lld%lld%lld",&l,&r,&s,&e);
		int d=(e-s)/(r-l);
		a[l]+=s,a[l+1]+=-s+d,a[r+1]+=-d-e,a[r+2]+=e;
	}
	int ans=0;
	for(int i=1;i<=n;++i){
		pre[i]=pre[i-1]+a[i];
		pre2[i]=pre2[i-1]+pre[i];
		ans^=pre2[i];
	}
	printf("%lld\n",ans);
} 

猜你喜欢

转载自www.cnblogs.com/youddjxd/p/12732784.html