3529: [Sdoi2014]数表

Description

    有一张N×m的数表,其第i行第j列(1 < =i < =礼,1 < =j < =m)的数值为
能同时整除i和j的所有自然数之和。给定a,计算数表中不大于a的数之和。

Input

    输入包含多组数据。
    输入的第一行一个整数Q表示测试点内的数据组数,接下来Q行,每行三个整数n,m,a(|a| < =10^9)描述一组数据。

Output

    对每组数据,输出一行一个整数,表示答案模2^31的值。

Sample Input

2
4 4 3
10 10 5

Sample Output

20
148

HINT

1 < =N.m < =10^5  , 1 < =Q < =2×10^4

Source

 
讲道理这种推公式的问题真的是我的缺陷啊,真的感觉有点难啊。经过借鉴很多的博客然后根据这几天的学习我们是可以推出这个公式的。。
   F[i]代表最大gcd(a,b)为i的约数的和为多少,这个东西我们可以暴力的枚举i就可以事前处理好的,
要是没有a的限制我们就能在sqrt(n)的时间内得到这个东西的解,但是现在有了a的限制我们应该怎么做啊,其实就是把在线的算法改成了离线的算法,就是用一个树状数组来为维护一个前缀和,这样子我们每次询问的复杂度就变成了sqrt(N)*lonN但是这个复杂度还是可以过的。
现在重要的问题就是如何树状数组来解决这个问题,我们事先把F[i]按照从大到小的顺序排序,然后我们把询问也按照从小到大的顺序排序,
对于每一次询问我们应该找到所有的F[i]<=a[x]的全部的i然后把它们添加到原来的i位置,注意是原来的i的位置不是现在的i的位置,这是非常的重要的,
然后我么用树状数组然后维护一下前缀和就行了。要是你们现在还不知道树状数组是什么东西,那你们可以用线段树解决这个问题啊。
还有一个要注意的地方就是要最后取模,应该是取模取的多的时候应该也是消耗时间的。
 
posted @ 2017-02-22 09:36  Heilce  阅读(154)  评论(0编辑  收藏  举报