Luogu P4231 三步必杀

gate
来清理下以前收藏的水题吧...
这道题是NOIP2018之前学长们押的题之一,虽然当时不会写,但是做法现在还记得

将一个数组上加一个等差数列,两次差分即可。
等差数列首项为s,末项为e,那么就有

        l    l+1    l+2    l+3    ...    r    r+1    r+2
a[i]    s    s+d    s+2d   s+3d   ...    e    0      0
b[i]    s    d      d      d      ...    d    -e     0
c[i]    s    d-s    0      0      ...    0    -e-d   e

因此,需要改动的就只有l, l+1, r+1, r+2这四项


代码如下

const int maxn = 1e7+10;

int n,m,l,r;
long long s,e,d,sum,ans;
long long a[maxn],b[maxn];

int main() {
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= m; i++) {
		scanf("%d%d%lld%lld",&l,&r,&s,&e);
		d = (e-s)/(r-l);
		b[l] += s;
		b[l+1] += d-s;
		b[r+1] += -e-d;
		b[r+2] += e;
	}
	for(int i = 1; i <= n; i++) {
		b[i] += b[i-1];
		a[i] += a[i-1] + b[i];
		sum ^= a[i];
		ans = max(ans,a[i]);
	}
	printf("%lld %lld",sum,ans);
	return 0;
}
原文地址:https://www.cnblogs.com/mogeko/p/12655913.html