CF1207F Remainder Problem

CF1207F. Remainder Problem 暴力分治

Notes

给定一个50万大小的一维数组,有以下两个操作,进行最多50万次询问

  • 1 xxx yyya[x]加上yyy

  • 2 xxx yyy 求在aaa数组中所有imodx=yi mod x =yimodx=ya[i]的和
    image-20201023000828027
    复杂度证明

  • 假设以BBB为界,预处理出模数小于BBB的答案,查询时如果模数小于BBB就直接返回。预处理BBB矩阵所用时间为O(B)O(B)O(B)

  • 模数大于BBB,暴力计算所用时间为O(NB)→求每个数消耗的时间,这里不要省去BO(\frac{N}{B})\to 求每个数消耗的时间,这里不要省去BO(BN)B

每个查询的复杂度可以表示为
O(NB+B)→Omin=Min(NB+B)  ⟺  NB+B≥NB×B=N(NB=B时) O(\frac{N}{B}+B) \to O_{min}=Min(\frac{N}{B}+B) \iff\frac{N}{B}+B\geq \sqrt{\frac{N}{B}\times B}= \sqrt{N} (\frac{N}{B}=B时) O(BN+B)Omin=Min(BN+B)BN+BBN×B=N(BN=B)
所以总复杂度为

O(q×N) O(q\times \sqrt{N}) O(q×N)

Code

#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define mod 1000000007
const ll maxn = 2e6 + 7;
int a[600000];
int ans[800][800];//记录所有k=(1~5e5)中所有a[k]%i==j的和

int main() {
	ios::sync_with_stdio(false);
    int q, t, x, y;
    cin >> q;
    while (q--) {
        cin >> t >> x >> y;
        if (t == 1) {
            a[x] += y;
            for (long long i = 1; i <= 750; ++i) {
                ans[i][x % i] += y;
            }

        } else if (t == 2) {
            if (x <= 750) cout << ans[x][y] << '\n';
            else {
                ll tmp = 0;
                for (long long i = y; i <= 500000; i += x) {
                    tmp += a[i];
                }
                cout << tmp << '\n';
            }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值