Educational Codeforces F. Remainder Problem

[传送门]

题意就是单点加以及查询下标为等差数列位置上的值之和。
刚开始看到这道题。我以为一个数的倍数是log级别的。就直接写了发暴力。就T了。还在想为啥,优化了几发才发现不太对劲。
然后才想到是$\dfrac {n}{x}$级别的。不过看到$\dfrac {n}{x}$应该就出来了。
当$x \leq \sqrt n$时用$sum[i][j]$表示公差为$i$,首项为$j$的和。修改时可以$O(\sqrt n)$修改,查询就可以$O(1)$了。
当$x > \sqrt n$时直接暴力就行了。

#include <bits/stdc++.h>
using namespace std;
 
const int N = 5e5;
int sum[900][900];
int a[N + 7];
 
int main() {
    int q;
    scanf("%d", &q);
    while (q--) {
        int opt, x, y;
        scanf("%d%d%d", &opt, &x, &y);
        if (opt == 1) {
            a[x] += y;
            for (int i = 1; i <= 800; i++) {
                sum[i][x % i] += y;
            }
        } else {
            if (x > 800) {
                int ans = 0;
                for (int i = y; i <= N; i += x) ans += a[i];
                printf("%d\n", ans);
            } else {
                printf("%d\n", sum[x][y]);
            }
        }
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Mrzdtz220/p/11673202.html