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; }