Educational Codeforces Round 71 (Rated for Div. 2) - F. Remainder Problem(根号分治)

题目链接:https://codeforces.com/contest/1207/problem/F

题意:一个长度为的数组,初始为空,支持两种操作:

  • 1,x,y,表示将a[x]+y
  • 2,x,y,表示求所有下标模 x 为 y 的数的和

思路:分成两部分,\sqrt{5e5}\approx 710,对于 x 大于710的直接暴力求和,小于等于710的维护一个b[i][j]表示模 i 为 j 的sum和。对于每一个1操作,x只对x\%i有贡献,所以b[i][x \% i] += y(1\leq i\leq 710)

#include 
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef pair pii;
typedef pair pll;
#define mp make_pair
#define pb push_back
#define all(x) x.begin(), x.end()
#define bug prllf("*********\n")
#define debug(x) cerr<<#x<<" = "<<(x)< '9') {if(ch == '-') f = -1; ch = getchar();}
    while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int a[N], b[720][720];
int main()
{
    IO; int q; cin >> q;
    while(q--)
    {
        int op, x, y;
        cin >> op >> x >> y;
        if(op == 1)
        {
            a[x] += y;
            for(int i = 1; i <= 710; i++) b[i][x % i] += y;
        }
        else
        {
            if(x <= 710) cout << b[x][y] << endl;
            else
            {
                ll ans = 0;
                for(int i = y; i <= 5e5; i += x) ans += a[i];
                cout << ans << endl;
            }
        }
    }
    return 0;
}

 

你可能感兴趣的:(【优美的暴力------分块】)