有三个下标从1到n的数组a、b、c。
a数组初始全为0。
b[i]=∑j|ia[j]
c[i]=∑j|ib[j]
需要进行下列操作:
1 x y :将a[x]加上y
2 x :询问当前c[x]的值
第一行两个整数,n和q,分别表示数组下标范围和操作次数。(1<=n,q<=1,000,000) 接下来q行,描述一个操作。(x随机,1<=x<=n,1<=y<=10^6)
对于每一个第二种操作输出一个答案。
5 5 1 2 4 2 2 2 4 1 1 3 2 5
4 8 6
题解:这题也是醉了。用暴力就行。
对于每个a 数组元素,对它的下标整数倍b数组元素产生贡献,然后再对其下标整数倍的c 数组元素产生影响。
那么对于a[x] 和c[y] ,通过简单的推算就可以知道a[x] 对c[y] 的贡献倍数为yx 的约数个数倍
PS:只有当y为x倍数的时候才可能有贡献,不妨设y为x的z倍,那么a-b-c要有贡献的话b是a的x1倍,c是b的y1倍,c是a的x1*y1倍,那么只有x1*y1=z时,才有贡献,也就是x1为z的约数是才有贡献。所以每对x,y的贡献为y*(z的约数的个数)
(可以理解为从x 到y 有多少种变换方法)然后就可以使用正常的方法去维护了(本题单点查改,不需要数据结构维护)
于是预处理1000000 以内每个数的约数个数。
维护的方法有两种
第一种:每修改一个a ,就修改其所有相关的c
第二种:每查询一个c ,就查询其所有相关的a
因为n的约数个数是n √ 级别的,所以说,然而一个数的倍数可能是n 级别的
于是乎,一般情况下都会选择第二种维护方式(每次查询n √ ),这么想的同学应该在51nod 上从第13 个点开始挂……(2500ms 左右跑过时间最长点)
这一道题中有个重要条件:x 随机
也就是说,x 的期望大小为500000 。这也就意味着,对于第二种维护方式,还是每次查询n √ 的期望查询次数。但是对于第一种维护方式,每次修改的期望修改次数只有2 。
于是这题选择第一种维护方式更优(快了不是一点)。
题解转自:点击打开链接