序列--(树状数组维护等差数列模板)

题目描述
eobiyye给了你一个长度为n的序列ai,序列中每个元素的初始值为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只想要知道最终序列每一项的异或和,即。(其中表示二进制下的异或操作,在c++中为^)
样例输入 Copy

5 2
1 5 2 10
2 4 1 1

样例输出

3

提示
样例解释:
第一次操作加的数列:2 4 6 8 10
第二次操作加的数列:0 1 1 1 0
所有操作结束后序列每个元素值为:2 5 7 9 10。
输出异或和,就是3。

【数据范围】
对于30%的数据:n,m≤1000 。
对于50%的数据:n,m≤100000。
对于另外20%的数据:s=e。
对于100%的数据:n,m≤500000,1≤l<r≤n。
数据保证输入数据以及在任何时候序列中的数在[0,9×1018]范围内。

本题输入文件较大,Geobiyye给了你一份快速读入的模板。

template <typename T> void read(T &x){
int f=1;x=0;char c=getchar();
for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
for (; isdigit(c);c=getchar()) x=x*10+c-'0';
x*=f;
}

你可以使用函数read(x)读入一个int或long long类型的整数。

以下为示范程序:

#include<bits/stdc++.h>
using namespace std;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
int n;
long long m;
int main(){
	read(n);//读入int类型变量n
	read(m);//读入long long类型变量m
	return 0;
}

这道题通过线段树和树状数组都可以完成,但是线段树比较复杂,代码也比较多~~(我懒)~~ ,然后写了写树状数组
这道题是洛谷上的一道类似的题,可以先了解一下洛谷上的这道题,然后两道题有异曲同工之妙,可以了解下
如果将洛谷上的题和这个题类比的话,先要进行预处理等差数列的首项,公差
a1=a1
a2=a1+d
a3=a1+2d

an=a1+(n-1)d
公差=>d== (an-a1)/(n-1)
==(ar-al) / (r-l)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll read(){
	ll c = getchar(),Nig = 1,x = 0;while(!isdigit(c) && c!='-')c = getchar();
    if(c == '-')Nig = -1,c = getchar();
    while(isdigit(c))x = ((x<<1) + (x<<3)) + (c^'0'),c = getchar();
    return Nig*x;}
#define read read()
const ll inf = 1e15;
const ll INF = 0x3f3f3f3f;
const int maxn = 5e5 + 7;
const int mod = 1e9+9;
typedef int itn;
#define pi 3.14159265358979323846
ll n,m;
ll a[maxn];
ll tree[maxn][2];
ll _low_b(ll x){ return x&(-x); }
void _add(int pos,ll s,ll e){
    ///       位置 首相  公差
    for(int i=pos;i<=n;i+=_low_b((ll)i)){
        tree[i][0]+=s;tree[i][1]+=e;
        s+=e*(_low_b((ll)i));
    }
}
ll _GetSum(int pos){
    ll sum=0;
    int tx=pos;
    while(tx){
        sum+=tree[tx][0]+tree[tx][1]*(pos-tx);
        tx-=_low_b((ll)tx);
    }return sum;
}
int main()
{
    n=read,m=read;
    for(int i=1;i<=m;i++){
        int left=read,right=read;
        ll shou=read,mo=read;
        ll cha=mo-shou;
        cha/=(right-left);
        _add(left,shou,cha);
        _add(right+1,-1*(right+1-left)*cha-shou,-cha);
    }
    ll res=0;
    for(int i=1;i<=n;i++){ res^=_GetSum(i); }
    cout<<res<<endl;
    return 0;
}
/**
5 2
1 5 2 10
2 4 1 1
**/

原文地址:https://www.cnblogs.com/PushyTao/p/13675762.html