P4231 三步必杀(二阶差分)

题目

P4231 三步必杀(二阶差分)_第1张图片
P4231 三步必杀(二阶差分)_第2张图片

P4231 三步必杀(二阶差分)_第3张图片

输入输出样例
输入样例一

5 2
1 5 2 10
2 4 1 1

输出样例一

3 10

输入样例二

6 2
1 5 2 10
2 4 1 1

输出样例二

3 10

题解

  • a [    ] a[\ \ ] a[  ]为原数组, b [    ] b[\ \ ] b[  ] a [    ] a[\ \ ] a[  ]的差分数组, c [    ] c[\ \ ] c[  ] b [    ] b[\ \ ] b[  ]的差分数组
  • 对于 l , r , s , t l,r,s,t l,r,s,t我们可以算出公差为 d = t − s r − l d=\frac{t-s}{r-l} d=rlts
  • 那么 a [    ] a[\ \ ] a[  ]数组中数字的改变为 a [ i ] = a [ i ] + s + d ∗ ( i − l )       ( l ≤ i ≤ r ) a[i]=a[i]+s+d*(i-l) \ \ \ \ \ (l \leq i \leq r) a[i]=a[i]+s+d(il)     (lir)
  • b [    ] b[\ \ ] b[  ]数组中数字( b [ i ] = a [ i ] − a [ i − 1 ] b[i]=a[i]-a[i-1] b[i]=a[i]a[i1])的改变为
    b [ l ] = a [ l ] + s − a [ l − 1 ] = b [ l ] + s b[l]=a[l]+s-a[l-1]=b[l]+s b[l]=a[l]+sa[l1]=b[l]+s
    b [ i ] = a [ i ] + d ∗ ( i − l ) − a [ i − 1 ] − d ∗ ( i − 1 − l ) = b [ i ] + d        ( l + 1 ≤ i ≤ r ) b[i]=a[i]+d*(i-l)-a[i-1]-d*(i-1-l) = b[i]+d \ \ \ \ \ \ (l+1\leq i \leq r) b[i]=a[i]+d(il)a[i1]d(i1l)=b[i]+d      (l+1ir)
    b [ r + 1 ] = a [ r + 1 ] − ( a [ r ] + t ) = b [ r + 1 ] − t b[r+1]=a[r+1]-(a[r]+t)=b[r+1]-t b[r+1]=a[r+1](a[r]+t)=b[r+1]t
  • c [    ] c[\ \ ] c[  ]数组中数字( c [ i ] = b [ i ] − b [ i − 1 ] c[i]=b[i]-b[i-1] c[i]=b[i]b[i1])的改变为
    c [ l ] = b [ l ] + s − b [ l − 1 ] = c [ l ] + s c[l]=b[l]+s-b[l-1]=c[l]+s c[l]=b[l]+sb[l1]=c[l]+s
    c [ l + 1 ] = b [ l + 1 ] + d − ( b [ l ] + s ) = c [ l + 1 ] + d − s c[l+1]=b[l+1]+d-(b[l]+s) = c[l+1]+d-s c[l+1]=b[l+1]+d(b[l]+s)=c[l+1]+ds
    c [ i ] = ( b [ i ] + d ) − ( b [ i − 1 ] + d ) = c [ i ]         ( l + 2 ≤ i ≤ r ) c[i]=(b[i]+d)-(b[i-1]+d)=c[i] \ \ \ \ \ \ \ (l+2\leq i \leq r) c[i]=(b[i]+d)(b[i1]+d)=c[i]       (l+2ir)
    c [ r + 1 ] = ( b [ r + 1 ] − t ) − ( b [ r ] + d ) = c [ r + 1 ] − t − d c[r+1]=(b[r+1]-t)-(b[r]+d)=c[r+1]-t-d c[r+1]=(b[r+1]t)(b[r]+d)=c[r+1]td
    c [ r + 2 ] = b [ r + 2 ] − ( b [ r + 1 ] − t ) = c [ r + 2 ] + t c[r+2]=b[r+2]-(b[r+1]-t)=c[r+2]+t c[r+2]=b[r+2](b[r+1]t)=c[r+2]+t
  • 统计时求两遍前缀和即可

code

#include  
using namespace std; 
typedef long long LL; 
const int maxn = 1e7 + 100; 

template <typename T> 
inline void read(T &s) {
	s = 0; 
	T w = 1, ch = getchar(); 
	while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); }
	while (isdigit(ch)) { s = (s<<1) + (s<<3) + (ch^48); ch = getchar(); }
	s *= w; 
}

int n, m; 
LL a[maxn]; 

int main() {
	read(n), read(m); 
	for (int i = 1; i <= m; ++i) {
		LL l, r, s, t; 
		read(l), read(r), read(s), read(t);  
		LL d = (t-s) / (r-l); // 公差 
		a[l] += + s; 
		a[l+1] += d - s; 
		a[r+1] -= d + t; 
		a[r+2] += t; 
	}
	LL sum1 = 0ll, sum2 = 0ll, ans = 0ll, Max = 0ll;
	for (int i = 1; i <= n; ++i) {
		sum1 += a[i]; 
		sum2 += sum1; 
		Max = max(Max, sum2); 
		ans ^= sum2; 
	}
	printf("%lld %lld\n", ans, Max); 
	return 0; 
}

你可能感兴趣的:(题解————题解,基本算法——差分,基本算法——基本算法)