[jzoj]4216.NOIP2015模拟9.12平方和

Posted Philchieh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[jzoj]4216.NOIP2015模拟9.12平方和相关的知识,希望对你有一定的参考价值。

Link

  https://jzoj.net/senior/#main/show/4216

Description

  给出一个N个整数构成的序列,有M次操作,每次操作有一下三种:

  ①Insert Y X,在序列的第Y个数之前插入一个数X;
  ②Add L R X,对序列中第L个数到第R个数,每个数都加上X;
  ③Query L R,询问序列中第L个数到第R个数的平方和。

Solution

  我不会告诉你这道题我打了10000+byte,并且改了2个月,50多个小时,删掉代码重打了5次。这道题用splay来弄是十分简单的一道裸体。但是我这种渣渣只能用可行的线段树。别人一次能打对,我仍要检查许多线段树的细节,并且打了N多个操作。可能是我代码风格不好吧。但为了方便检查也只好这样了。

30分

  显然,暴力去做,可以拿到拿烂的部分分。

50分
  在30分的基础上,数据增大, 但是没有Insert的操作,所以是线段树裸题。

100分

  大佬肯定是一眼切。这是道Splay练手题目,可以看看gmh大神的题解,异常详细。请允许我打个广告。http://blog.csdn.net/gmh77

  Splay以后我会推进并且更改这个博文。现在我只会线段树。

  对于前两个操作,显然就是线段树裸题,毋庸置疑的。

  但是,因为有了Insert操作,导致我们线段树的下标代表的数不一样。既然在线不可以,离线总是可以的。

  ①线段树1(前缀和)维护位置

  在原本序列的第i个数和i-1个数之间(包括i),插入了多少个数。

  最终用线段树1维护了出来之后,我们很容易的知道了原本序列的数他在最终序列的位置。这是值得你思考的地方

  ②线段树2维护最终序列

  我们知道了原本序列每一个数在最终序列对应的位置,那么理所当然地可以再种一棵线段树2来维护插入的数的最终位置。

  一开始把原序列的数,在最终序列对应位置,标记在线段树那个位置上,0表示当前位置不选,反之。这样一个前缀和就知道最终序列第i个位置之前(包括i)一共出现了多少个数。

  那么每次插入一个数,我们二分出一个i,满足i最小,设1~i前缀和为sum。则满足sum=插入在哪个位置之前-1。这个位置,便是你当前插入的数在最终序列的位置。愉快地记录下来。

  前缀和用线段树2维护。

  如果正着做必然会错。倒着做才是对的。这是你值得思考的。

  因为后放的,必然在左边。

  ③线段树3,4,5维护最终序列

  我们可以用正常线段树来做了,因为我们可以通过最终位置来确定其对应的线段树下标。

  但是平方和又是一个棘手的问题。

  分解一下。

  (a+b)²=a²+b²+2ab。

  显然,每次加一个数,b就是这个加的数。

  a²为原本的平方和,故用线段树3来维护他。

  2ab,其中如果有多个a,那么就是2b(a1+a2+a3.....+an),那么维护线段树4维护和即可。

以上是关于[jzoj]4216.NOIP2015模拟9.12平方和的主要内容,如果未能解决你的问题,请参考以下文章

校内模拟赛(9.12)

[jzoj]2938.NOIP2012模拟8.9分割田地

jzoj6.24模拟B

jzoj2017-8-18提高组ANOIP模拟赛

jzoj5141 NOI2017模拟6.12说无可说

纪中模拟2019.08.17JZOJ3503粉刷