【COCI 2009】ALADIN

题目大意

要求维护一个长度为 n 的序列,有两种操作,共 m 个询问。

  1. 将区间 [l,r) 上的数进行修改,位置 i 上的数改为 iAmodB
  2. 询问区间 [l,r) 上的数的和。

其中 n<=109,m<=105

分析

注意这里是将数模了,询问总和时不模。
离散化以后套个线段树就可以处理好两种询问,问题在于怎么求这样一个东西。

ni=0(iAmodB)

考虑将取模转换一下形式。

ni=0(iAmodB)=Ani=0iBni=0iAB

左边的很好算,主要看右边的取整求和部分。
几何化地理解一下,实际上它求的是一个以 (0,0),(n,0),(n,nAB) 为顶点的三角形内或边缘上的整点数目(不考虑落在坐标轴上的底边)。
不妨分类讨论。
A>B ,则 A 可以写成 A=kB+r ,其中 k,r 都是非负整数。
那么就有

ni=0iAB=ni=0i(kB+r)B=ni=0irB+kni=0i

那么就转化为了 A<B 的情况。
对于这种情况我们不妨反过来算,算矩形点数减去上三角形点数来得到下三角形点数,设 nAB=m

ni=0iAB=nmmi=0iBA+diagonal

其中 diagonal 代表落在对角线上的整点,它的值是 ngcd(A,B)B 。因为这条直线必定过点 (B,A) ,而它与 (1,1) 形成的线段上有 gcd(A,B) 个整点,每个整点的横坐标之间差了 Bgcd(A,B) 个单位,于是 n 个单位再除一下就好了。

注意到我们的问题转化为了求 mi=0iBA ,也就是说 A B 调换了位置,那么又转化回了 A>B 的问题。这样子类似于欧基里德算法地计算,时间复杂度是 O(logn)

然后剩下的就是简单的线段树维护了。
总时间复杂度 O(nlog2n)

后记

要注意取模转化的技巧,以及数论知识的运用。

你可能感兴趣的:(【COCI 2009】ALADIN)