题目描述

问题摘要:

N个柱子排成一排,一开始每个柱子损伤度为0。

接下来勇仪会进行M次攻击,每次攻击可以用4个参数l,r,s,e来描述:

表示这次攻击作用范围为第l个到第r个之间所有的柱子(包含l,r),对第一个柱子的伤害为s,对最后一个柱子的伤害为e。

攻击产生的伤害值是一个等差数列。若l=1l,r=5,s=2,e=10,则对第1~5个柱子分别产生2,4,6,8,10的伤害。

鬼族们需要的是所有攻击完成之后每个柱子的损伤度。

输入格式

第一行2个整数N,M,用空格隔开,下同。

接下来M行,每行4个整数l,r,s,e,含义见题目描述。

数据保证对每个柱子产生的每次伤害值都是整数。

输出格式

由于输出数据可能过大无法全部输出,为了确保你真的能维护所有柱子的损伤度,只要输出它们的异或和与最大值即可。

(异或和就是所有数字按位异或起来的值)

(异或运算符在c++里为^)

输入输出样例

输入 #1

5 2

1 5 2 10

2 4 1 1

输出 #1

3 10

输入 #2

6 2

1 5 2 10

2 4 1 1

输出 #2

3 10

说明/提示

样例解释:

样例1:

第一次攻击产生的伤害:2 4 6 8 10

第二次攻击产生的伤害:0 1 1 1 0

所有攻击结束后每个柱子的损伤程度:2 5 7 9 10。

输出异或和与最大值,就是3 10。

样例2:

没有打到第六根柱子,答案不变

看到要加等差数列,我们很自然的会想到差分。

数据范围:

本题满分为100分,下面是4个子任务。(x/y)表示(得分/测试点数量)

妖精级(18/3):1⩽n,m⩽1000。这种工作即使像妖精一样玩玩闹闹也能完成吧?

河童级(10/1):s=e,这可以代替我工作吗?

天狗级(20/4):1⩽n⩽10^5,1⩽m⩽10^5。小打小闹不再可行了呢。

鬼神级(52/2):没有特殊限制。要真正开始思考了。

以上四部分数据不相交。

对于全部的数据:1⩽n⩽10^7,1⩽m⩽3×10^5,1⩽l<r⩽n.

所有输入输出数据以及柱子受损伤程度始终在[0,9×10^18]范围内。

分析

我们手玩一下样例,对等差数列进行差分,会得到一个这样的数列

2,2,2,2,2,-10

发现我们还要每次都遍历一遍,给差分数组加上,这样复杂度会很高。

我们考虑对差分数组在进行一遍差分,就会变成

2 0 0 0 0 ,-12,12

这样你就会发现,我们只要给四个位置加上就行了。

分别是 dd[l] ,dd[l+1],dd[r+1],dd[r+2](dd为对差分数组进行差分之后的结果)

设等差数列的公差为t,首项为st,尾项为en

那么 dd[l] += st; dd[l+1] += t-st; dd[r+1] -= en+t; dd[e+2] += en+t;

之后我们对dd数组求一下前缀和,就可以得到差分数组。

在对差分数组求一下前缀和,就是改变后的序列.

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,l,r,st,en,t;
long long ans,maxn,d[10000010],sum[10000010],a[10000010];
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s = s * 10+ch -'0'; ch = getchar();}
return s * w;
}
int main()
{
n = read(); m = read();
for(int i = 1; i <= m; i++)
{
l = read(); r = read(); st = read(); en = read();
t = (en - st) / (r-l);//t是等差数列的公差
d[l] += st;//上面的柿子
d[l+1] += t-st;
d[r+1] -= en+t;
d[r+2] += en;//d是对差分数组差分得到的结果
}
for(int i = 1; i <= n; i++)
{
a[i] = a[i-1] + d[i];//a为差分数组
sum[i] = sum[i-1] + a[i];//sum为改变之后的序列
ans ^= sum[i];
maxn = max(maxn,sum[i]);
}
printf("%lld %lld\n",ans,maxn);
return 0;
}

ENDING

P4231 三步必杀的更多相关文章

  1. Luogu P4231 三步必杀 (差分)

    目录 题目 题解 题目 题目链接 题目背景 (三)旧都 离开狭窄的洞穴,眼前豁然开朗. 天空飘着不寻常的雪花. 一反之前的幽闭,现在面对的,是繁华的街市,可以听见酒碗碰撞的声音. 这是由被人们厌恶的鬼 ...

  2. 【luogu P4231 三步必杀】 题解

    题目链接:https://www.luogu.org/problemnew/show/P4231 诶 我很迷啊..这跟树状数组有什么关系啊...拿二阶差分数组过了..? #include <cs ...

  3. 【Luogu】P4231三步必杀(差分,差分)

    题目链接 郑重宣布我以后真的再也不会信样例了,三种写法都能过 另:谁评的蓝题难度qwq 蓝题有这么恐怖吗 两次差分,第一次差分,前缀和求出增量数组,第二次求出原数组顺便更新答案 看题解之后……第二次差 ...

  4. luogu P4231 三步必杀

    嘟嘟嘟 这道题就是区间加一个等差数列,然后最后求每一个数的值. O(n)做法:二阶差分. 其实就是差分两遍.举个例子 0 0 0 0 0 0 0,变成了 0 2 4 6 8 0 0.第一遍差分:0 2 ...

  5. 洛谷P4231 三步必杀

    题目描述: $N$ 个柱子排成一排,一开始每个柱子损伤度为0. 接下来勇仪会进行$M$ 次攻击,每次攻击可以用4个参数$l$ ,$r$ ,$s$ ,$e$ 来描述: 表示这次攻击作用范围为第$l$ 个 ...

  6. luoguP4231_三步必杀_差分

    luoguP4231_三步必杀_差分 题意:N 个柱子排成一排,一开始每个柱子损伤度为0.接下来勇仪会进行M 次攻击,每次攻击可以用4个参数l,r ,s ,e 来描述: 表示这次攻击作用范围为第l个到 ...

  7. [Luogu]三步必杀

    Description Luogu4231 Solution 我最近到底怎么了,这种题都做不出来了,一看题第一反应李超线段树(虽然不会),觉得不可做,看一眼题解才发现这个题可以差分,然后差分还打错了好 ...

  8. Membership三步曲之进阶篇 - 深入剖析Provider Model

    Membership 三步曲之进阶篇 - 深入剖析Provider Model 本文的目标是让每一个人都知道Provider Model 是什么,并且能灵活的在自己的项目中使用它. Membershi ...

  9. Membership三步曲之入门篇 - Membership基础示例

    Membership 三步曲之入门篇 - Membership基础示例 Membership三步曲之入门篇 -  Membership基础示例 Membership三步曲之进阶篇 -  深入剖析Pro ...

随机推荐

  1. Mono生命周期小实验

    今天在写代码的时候,遇到一个初始化顺序问题,于是做了一个实验,下面记录结果: 情景: 1.在 脚本A中实例化 一个预制体,该预制体挂有脚本B 2.在 脚本A中,获取实例化物体 身上的 脚本B,并且设置 ...

  2. bootstrap的时间控件使用(双日历)

    这段时间看了下bootstrap的时间控件,发现使用起来还是很简单的,趁着有时间的时候整理了一下,方便自己以后忘记的时候查阅... 废话不多说先上效果图 接下来是代码实现 第一步当然是导入css.js ...

  3. Codeforces1312E Array Shrinking 区间DP

    题意 给你一个数组\(a\),只要满足\(a_i=a_{i+1}\)就可以将这两个元素合并成一个值为\(a_i+1\)的元素,问数组最小长度. 解题思路 记得之前某场的F和这题差不多,当时好像是相邻且 ...

  4. MySQL通过实体经纬度字段插入数据库point类型的经纬度字段

    说明:数据库:表中没有经度跟纬度字段,只有location字段(point类型) POINT(经度 纬度)实体类:只有经度 lng 字段.纬度 lat 字段 没有location字段 <!--添 ...

  5. 【NOIP2013模拟】黑魔法师之门

    题目描述 经过了16个工作日的紧张忙碌,未来的人类终于收集到了足够的能源.然而在与Violet星球的战争中,由于Z副官的愚蠢,地球的领袖applepi被邪恶的黑魔法师Vani囚禁在了Violet星球. ...

  6. Appium自动化Android环境搭建

      前言: 本系列教程用于个人经验记录,用于他人借鉴,提供一定参考价值.经常会有一种感觉,工具或技术在某一阶段使用比较熟练,过一段时间就可能会遗忘,俗话说好记性不如烂笔头,以此记录. appium简介 ...

  7. Ubuntu中的launcher

    最近在ubuntu系统中下载了最新版的eclipse,在一个临时文件夹中解压了eclipse压缩包,然后打开eclipse,按平时常规做法,我在launcher里右键点击eclipse,选择“锁定到启 ...

  8. 查看windows和linux下端口是否被占用

    1.windows cmd输入netstat -ano |findstr "端口号" 查看到1202端口被使用的进程PID是10692 输入tasklist |findstr 10 ...

  9. 第3课 - makefile伪目标的引入

    第3课 - makefile伪目标的引入 1. makefile 中的目标究竟是什么? (1)默认情况下,make 认为目标对应着一个文件  ==>  目标即文件名 (2)make 首先会检测目 ...

  10. Linux下用户的创建与删除

    我们在Linux下创建用户主要有两种方式:adduser和useradd,它们的区别以及主要用法如下: adduser adduser的用法很简单,只需adduser+username即可,如下: s ...