世 上 没 有 绝 望 的 处 境
只 有 对 处 境 绝 望 的 人
题目介绍
题目描述
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只想要知道最终序列每一项的异或和,即a1⊕a2⊕a3⊕……⊕an。其中⊕表示二进制下的异或操作,在c++中为^)
测试样例
Sample Input
5 2
1 5 2 10
2 4 1 1
Sample Output
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和an,你也知道l 和 r,所以你也知道数列的长度。经过多次的叠加之后,问你这个数列所有数的异或和是多少。
思路分析
这题思路就是一个差分数组的思想,只不过这个地方需要用到二维的差分,需要对你的等差数列进行差分。当我们进行一步差分的时候,我们可以得到公差,和首相。然后对这个数列进行差分,就可以用首和尾来表示整个数组。说起来有些抽象,请看下图:
之后就和差分数组的做法没什么区别了!
代码
#include<algorithm>
#include<iostream>
#include<string.h>
#include <iomanip>
#include<stdio.h>
#include<utility>
#include<vector>
#include<string>
#include<math.h>
#include<cmath>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
#pragma warning(disable:4244)
#define PI 3.141592653589793
#pragma GCC optimize(2)
#define accelerate cin.tie(NULL);cout.tie(NULL);ios::sync_with_stdio(false);
#define EPS 1.0e-8
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll ll_inf = 9223372036854775807;
const int int_inf = 2147483647;
const short short_inf = 32767;
const char char_inf = 127;
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline 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;
}
inline void out(ll a) {
if (a < 0)putchar('-'), a = -a;
if (a >= 10)out(a / 10);
putchar(a % 10 + '0');
}
ll phi(ll n)
{
ll ans = n, mark = n;
for (ll i = 2; i * i <= mark; i++)
if (n % i == 0) { ans = ans * (i - 1) / i; while (n % i == 0)n /= i; }
if (n > 1)ans = ans * (n - 1) / n; return ans;
}
ll qpow(ll x, ll n, ll mod) {
ll res = 1;
while (n > 0) {
if (n & 1)res = (res * x) % mod;
x = (x * x) % mod;
n >>= 1;
}
return res;
}
ll mat_mod;
struct Mat {
ll m[10][10];
};
Mat Mul(Mat A, Mat B, ll mat_size) {
Mat res;
memset(res.m, 0, sizeof(res.m));
for (int i = 0; i < mat_size; i++)for (int j = 0; j < mat_size; j++)for (int k = 0; k < mat_size; k++)
res.m[i][j] = (res.m[i][j] + (A.m[i][k] * B.m[k][j]) % mat_mod) % mat_mod;
return res;
}
Mat mat_qpow(Mat data, ll power, ll mat_size) {
Mat res;
memset(res.m, 0, sizeof(res.m));
for (int i = 0; i < mat_size; i++)res.m[i][i] = 1;
while (power) {
if (power & 1)res = Mul(res, data, mat_size);
data = Mul(data, data, mat_size), power >>= 1;
}
return res;
}
#define Floyd for(int k = 1; k <= n; k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
#define read read()
ll save[1000005];
void solve()
{
ll l = read, r = read, a = read, end = read, d, len;
len = r - l;
d = (end - a) / len;
save[l] += a;
save[l + 1] += (d - a);
save[r + 1] -= a + (len + 1) * d;
save[r + 2] += a + len * d;
}
int main()
{
ll n = read;
ll T = read;
while (T--)solve();
for (ll i = 2; i <= n; i++)
save[i] += save[i - 1];
for (ll i = 2; i <= n; i++)
save[i] += save[i - 1];
ll ans = 0;
for (ll i = 1; i <= n; i++)ans ^= save[i];
cout << ans << endl;
}