题解 P4231 【三步必杀】

知识点:差分

原题面

题目要求:

给定一长度为 \(n\) 的 初始全 \(0\) 的数列 \(a\), 给定 \(m\) 次修改操作

对于每次修改操作, 给定四个参数: \(l,r,s,e\)
表示 修改范围为\([l,r]\), 对 \(a[l]+=s\) , 对 \(a[r]+=e\)
每次修改的 值为一个等差数列 , 首项为 \(s\) , 尾项为 \(e\) , 长度为 \((r-l+1)\)

求数列中 所有修改完成后
所有元素的 异或和 与 最大值
\(n \le 1e7, m \le 3e5\) ,时间限制 \(500ms\)

分析题意:

  • 这么鬼畜的 数据范围与时间限制,
    无外部优化情况下, 只可使用 \(O(n)\) 算法
    则对于单次 修改, 必须是 \(O(1)\)

  • 如何 进行区间加一 等差数列操作?
    由于 等差数列 的等差性质 , 考虑进行差分:

    • 如下列等差数列:

      00 00 04 06 08 10 12 00 00

      进行一次差分后:

      00 00 04 02 02 02 02 -12 00 00

      发现 除了首元素外, 其他元素都相等, 相当于区间加操作
      则可再进行一次差分:

      00 00 04 -2 00 00 00 -14 12 00

      发现 只有四个位置被操作, 值有所改变

    • 通过 手玩多组数据 , 可以发现:
      若 将 \([l,r]\) 内 加上一首项为 \(s\) , 尾项为 \(e\) 的 等差数列, 公差为 \(d\)

      二次差分后 , 差分数组的变化为 :
      \(a[l] += s, a[l+1]+=(d-s)\)
      \(a[r+1] -=(d+e),a[r+2]+=e\)

      则对于 一次修改操作, 可以通过 二次差分, 做到 \(O(1)\) 的复杂度

  • 虽然 修改次数较多,
    但只需要最后进行一次查询,
    所以可以考虑 \(O(1)\)差分,
    再通过 二次取前缀和 \(O(n)\) 还原


//
/*
By:Luckyblock
*/
#include<cstdio>
#include<ctype.h>
#define max(a,b) (a>b?a:b)
#define int long long
const int MARX = 1e7+10;
//=============================================================
int n,m,ans1,ans2, diff[MARX],sum1[MARX],sum2[MARX];
//=============================================================
inline int read()
{
    int s=1, w=0; char ch=getchar();
    for(; !isdigit(ch);ch=getchar()) if(ch=='-') s =-1;
    for(; isdigit(ch);ch=getchar()) w = w*10+ch-'0';
    return s*w;
}
//=============================================================
signed main()
{
	n = read(), m = read();
	for(int i = 1; i <= m; i ++)
	{
	  int l = read(), r = read(), s = read(), e = read();
	  int d = (r == l)? 0 : (e-s)/(r-l);
	  diff[l] += s, diff[l+1] += (d-s), 
	  diff[r+1] -= (d+e), diff[r+2] += e;
	}
	
	sum1[1] = sum2[1] = diff[1], ans1 = ans2 = diff[1];
	for(int i = 2; i <= n; i ++)
	{
	  sum1[i] = sum1[i-1] + diff[i];
	  sum2[i] = sum2[i-1] + sum1[i];
	  ans1 ^= sum2[i], ans2 = max(ans2,sum2[i]);
	}
	printf("%lld %lld",ans1,ans2);	
}
posted @ 2019-10-11 21:59  Luckyblock  阅读(154)  评论(3编辑  收藏  举报