序列
时间限制: 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
a1⨁a2⨁a3⨁...⨁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,m≤500000,1≤l<r≤n。
数据保证输入数据以及在任何时候序列中的数在
[
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)
读入一个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;
}
思路
差分
因为是等差数列所以
a
i
−
a
i
−
1
=
d
(
常
数
)
a_i-a_{i-1}=d(常数)
ai−ai−1=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=r−ld−kc[l]+=kc[l+1]−=kc[l+1]+=kc[r+1]−=kc[r+1]−=(r−l)d+kc[r+2]+=(r−l)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
(r−l)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;
}