序列

序列

时间限制: 1 Sec 内存限制: 128 MB

题目描述

e o b i y y e eobiyye eobiyye 给了你一个长度为 n n n 的序列 a i a_i ai,序列中每个元素的初始值为 0 0 0
接下来她会对这个序列进行 m m m 次操作,每次操作有 4 4 4 个参数 l , r , s , e l,r,s,e l,r,s,e,表示将区间 [ l , r ] [l,r] [l,r] 加上一个首项为 s s s,末项为 e e e 的等差数列。
若一次操作中 l = 1 , r = 5 , s = 2 , e = 10 l=1,r=5,s=2,e=10 l=1,r=5,s=2,e=10 ,则对序列中第 1 1 1~ 5 5 5 个数分别加上 2 , 4 , 6 , 8 , 10 2,4,6,8,10 2,4,6,8,10
现在 G e o b i y y e Geobiyye Geobiyye 要求你求出 m m m 次操作后序列中的每个数的值。

输入

第一行 2 2 2 个整数 n , m n,m n,m,表示序列长度和操作数。
接下来 m m m 行,每行 4 4 4 个整数 l , r , s , e l,r,s,e l,r,s,e,含义见题目描述。
数据保证等差数列中的每一项都是整数。

输出

由于输出数据过大, G e o b i y y e Geobiyye Geobiyye 只想要知道最终序列每一项的异或和,即 a 1 ⨁ a 2 ⨁ a 3 ⨁ . . . ⨁ a n a_1\bigoplus a_2 \bigoplus a_3 \bigoplus ...\bigoplus a_n a1a2a3...an。(其中表示二进制下的异或操作,在c++中为^

样例输入

5 2
1 5 2 10
2 4 1 1

样例输出

3

提示

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

数据范围

对于100%的数据: n , m ≤ 500000 , 1 ≤ l < r ≤ n n,m≤500000,1≤l<r≤n n,m500000,1lrn
数据保证输入数据以及在任何时候序列中的数在 [ 0 , 9 × 1 0 18 ] [0,9×10^{18}] [0,9×1018] 范围内。

本题输入文件较大, G e o b i y y e Geobiyye 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)读入一个intlong 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;
}

思路

差分
因为是等差数列所以 a i − a i − 1 = d ( 常 数 ) a_i-a_{i-1}=d(常数) aiai1=d() 那么可以维护一个差分数组 c i c_i ci
当每输入一个 l , r , k , d l,r,k,d l,r,k,d 时 令 d = d − k r − l c [ l ] + = k c [ l + 1 ] − = k c [ l + 1 ] + = k c [ r + 1 ] − = k c [ r + 1 ] − = ( r − l ) d + k c [ r + 2 ] + = ( r − l ) d + k d=\frac{d-k}{r-l}\\c[l]+=k\\c[l+1]-=k\\c[l+1]+=k\\c[r+1]-=k\\c[r+1]-=(r-l)d+k\\c[r+2]+=(r-l)d+k d=rldkc[l]+=kc[l+1]=kc[l+1]+=kc[r+1]=kc[r+1]=(rl)d+kc[r+2]+=(rl)d+k
解释一下 在 l l l 加上 k k k,在 l + 1 l+1 l+1 r r r 位置加上 d d d ,在 r + 1 r+1 r+1 的位置加上 ( r − l ) d + k (r-l)d+k (rl)d+k

#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
template <typename T>
inline void read(T &x) {
    x = 0;
    static int p;
    p = 1;
    static char c;
    c = getchar();
    while (!isdigit(c)) {
        if (c == '-')p = -1;
        c = getchar();
    }
    while (isdigit(c)) {
        x = (x << 1) + (x << 3) + (c - 48);
        c = getchar();
    }
    x *= p;
}
template <typename T>
inline void print(T x) {
    if (x<0) {
        putchar('-');
        x=-x;
    }
    static int cnt;
    static int a[50];
    cnt = 0;
    do {
        a[++cnt] = x % 10;
        x /= 10;
    } while (x);
    for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
    putchar(' ');
    //puts("");
}
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int maxn = 5e5+10;
int n,m;
ll ans;
__int128 c[maxn],l,r,k,d,sum;
inline void work() {
    read(n);
    read(m);
    while (m--) {
        read(l);
        read(r);
        read(k);
        read(d);
        d = (d - k) / (r - l);
        c[l] += k;
        c[l + 1] -= k;
        c[l + 1] += d;
        c[r + 1] -= d;
        c[r + 1] -= (k + (r - l) * d);
        c[r + 2] += (k + (r - l) * d);
    }
    for (int i = 1; i <= n; i++) {
        c[i] += c[i - 1];
        sum += c[i];
        ans ^= sum;
    }
    print(ans);
}
int main() {
    int T = 1;
    //scanf("%d", &T);
    while (T--) {
        work();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值