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——

posted @ 2024-10-07 09:45  Sirkey  阅读(3)  评论(0编辑  收藏  举报