Mahmoud and Ehab and the function
考试考到的签
原式子:
\(f_j = |\sum_{i = 1} ^ n (-1) ^{i-1} \times (a_i - b_{i + j})|\)
基本思路把 \(a_i\) 和 \(b_i\) 分开。
\(f_j = |\sum_{i = 1} ^ n (-1) ^{i-1} \times a_i - (-1) ^{i-1} \times b_{i+j}|\)
发现 \((-1) ^{i-1} \times a_i\) 没有修改是个定值,直接计算。
考虑修改:
-
修改区间长度为 2 的倍数可以忽略,因为是一加一减。
-
修改区间长度不为 2 的倍数,判断右端点或左端点的奇偶性,偶数就减,奇数就加。
接下来考虑 \((-1) ^{i-1} \times b_{i+j}\) 我们可以将每个 \(j\) 的该式子求出来。求的时候使用前缀和优化,就可以做到 \(O(1)\)。
求解答案时,将求出的 \((-1) ^{i-1} \times b_{i+j}\) 排序后二分出最接近 \((-1) ^{i-1} \times a_i\) 的。
#define ll long long
#define int ll
#define debug(x) cout<<#x<<"[:]"<<x,puts("");
#define FOR(i,a,b) for(ll i=(a); i<=(b); ++i)
#define ROF(i,a,b) for(ll i=(a); i>=(b); --i)
//
//
//
using namespace std;
inline ll read() {
ll f = 0, t = 0;
char c = getchar();
while (!isdigit(c)) t |= (c == '-'), c = getchar();
while (isdigit(c)) f = (f << 3) + (f << 1) + c - 48, c = getchar();
return t ? -f : f;
}
void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
const int MX = 6e5 + 10;
int a[MX], b[MX][3];
int f[MX];
int n,m,Q;
const int inf = 1e18 + 10;
int check(int sum) {
int l = 1, r = m - n + 1;
int ans1 = inf;
while(l <= r) {
int mid = (l + r) / 2;
if(f[mid] <= sum) ans1 = f[mid], l = mid + 1;
else r = mid - 1;
}
int ans2 = inf;
l = 1, r = m - n + 1;
while(l <= r) {
int mid = (l + r) / 2;
if(f[mid] >= sum) ans2 = f[mid], r = mid - 1;
else l = mid + 1;
}
return min(abs(sum - ans1), abs(sum - ans2));
}
signed main() {
ios::sync_with_stdio(0), cout.tie(0);
n = read(), m = read(), Q = read();
FOR(i,1,n) a[i] = read();
FOR(i,1,m) b[i][0] = read();
int sum = 0;
FOR(i,1,n) {
if(i % 2 == 1) sum += a[i];
else sum -= a[i];
}
FOR(i,1,m) {
b[i][1] = b[i - 1][1];
b[i][2] = b[i - 1][2];
if(i % 2 == 0) b[i][2] += b[i][0];
else b[i][1] += b[i][0];
}
FOR(i,1,m - n + 1) {
if(i % 2 == 0) f[i] = b[n + i - 1][2] - b[i - 1][2] - b[n + i - 1][1] + b[i][1];
else f[i] = b[n + i - 1][1] - b[i - 1][1] - b[n + i - 1][2] + b[i][2];
}
sort(f + 1,f + m - n + 2);
cout<<check(sum)<<"\n";
while(Q--) {
int l = read(), r = read(), w = read();
if(l > r) swap(l,r);
if((r - l + 1) % 2 == 1) {
if(r % 2 == 1) sum += w;
else sum -= w;
}
cout<<check(sum)<<"\n";
}
return 0;
}
——end——