Codeforces 1207F Remainder Problem

tags

根号分治

中文题面

给你一个由 500000 500000 500000 个整数(编号从 1 1 1 500000 500000 500000 )组成的数组 a a a 。最初 a a a 中的所有元素都为零。

您必须对这个数组进行两种类型的查询:

  • 1 1 1 x x x y y y - a x a_x ax 增加 y y y
  • 2 2 2 x x x y y y - 计算 ∑ i ∈ R ( x , y ) a i \sum\limits_{i \in R(x, y)} a_i iR(x,y)ai ,其中 R ( x , y ) R(x, y) R(x,y) 是所有从 1 1 1 500000 500000 500000 有余数 y y y modulo x x x 的整数的集合。

你能处理所有的查询吗?

输入

第一行包含一个整数 q q q ( 1 ≤ q ≤ 500000 1 \le q \le 500000 1q500000 ) - 查询次数。

然后是 q q q 行,每行描述一个查询。第 i i i 行包含三个整数 t i t_i ti x i x_i xi y i y_i yi 1 ≤ t i ≤ 2 1 \le t_i \le 2 1ti2 )。如果是 t i = 1 t_i = 1 ti=1 ,则是第一类查询、 1 ≤ x i ≤ 500000 1 \le x_i \le 500000 1xi500000 − 1000 ≤ y i ≤ 1000 -1000 \le y_i \le 1000 1000yi1000 。如果是 t i = 2 t_i = 2 ti=2 ,则是第二类查询、 1 ≤ x i ≤ 500000 1 \le x_i \le 500000 1xi500000

可以保证至少有一个查询属于 2 2 2 类型。

输出

为每个 2 2 2 类型的查询打印一个整数–答案。

思路

没有预处理,直接暴力,时间复杂度为O(q * n / x); 预处理时间复杂度O(nx),每次O(1)回答,O(x)修改,总时间复杂度O(nx),使用根号分治,当x <= 707时使用预处理方式解决,当x > 707时使用暴力算法解决,避免超时,本题得解

代码

#include <bits/stdc++.h>
using namespace std;

int s[708][708];
int v[500005];
// 707分界
inline void solve() {
    const int n = 500000;
    int m, x, y;
    char op;
    cin >> m;
    while (m--) {
        cin >> op >> x >> y;
        if (op == '2') {
            if (x <= 707) cout << s[x][y] << '\n';
            else {
                int res = 0;
                for (register int i = 0; i * x + y <= n; i++) res += v[i * x + y];
                cout << res << '\n';
            }
        }
        else {
            v[x] += y;
            for (register int p = 1; p <= 707; p++) s[p][x % p] += y;
        }
    }
}
int main() {
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    solve();
    return 0;
}
  • 22
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值