栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

「bzoj - 3922」Karin的弹幕

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

「bzoj - 3922」Karin的弹幕

给出一个长度为 n n n 的序列 { a n } {a_n} {an​},支持操作:

0 p v:使 a p : = a p + v a_p:=a_p+v ap​:=ap​+v;1 x_0 d:求 max ⁡ x 0 ⩽ p ⩽ n , d ∣ ( p − x 0 ) { a p } max_{x_0leqslant pleqslant n,dmid(p-x_0)}{a_p} maxx0​⩽p⩽n,d∣(p−x0​)​{ap​}。
1 ⩽ n , m ⩽ 7 × 1 0 4 1leqslant n,mleqslant7times10^4 1⩽n,m⩽7×104,在任意时刻 ∣ a i ∣ ⩽ 2 31 − 1 |a_i|leqslant2^{31}-1 ∣ai​∣⩽231−1, 1 ⩽ x 0 , d ⩽ n 1leqslant x_0,dleqslant n 1⩽x0​,d⩽n。

常见 trick 题,我直接对 d d d 阈值分治。

如果 d d d 比阈值大,直接暴力跑。

如果 d d d 比阈值小,也好搞,开阈值个线段树,保存等差数列即可。

注意两边的复杂度不同阶,调调阈值大概会快很多。

#include 
using namespace std;
#define cmin(x, ...) x = min({x, __VA_ARGS__})
#define cmax(x, ...) x = max({x, __VA_ARGS__})
#define fors(i, l, r, ...) for(int i = (l), i##end = (r), ##__VA_ARGS__; i <= i##end; i++)
#define dfors(i, r, l, ...) for(int i = (r), i##end = (l), ##__VA_ARGS__; i >= i##end; i--)
const int THRESHOLD = 20;
int n, m, a[70100];
struct segtree {
    int mx[280100], _l[70100], _r[70100], ton[70100];
    void decl(const int d) {
        int x = 0;
        fors(i, 1, d) {
            for(int j = i; j <= n; j += d) ton[_l[j] = ++x] = j;
            for(int j = i; j <= n; j += d) _r[j] = x;
        }
    }
    void build(int x, int l, int r) {
        if(l == r) {
            mx[x] = a[ton[l]];
            return;
        }
        int mid = (l+r)/2;
        build(x*2, l, mid), build(x*2+1, mid+1, r);
        mx[x] = max(mx[x*2], mx[x*2+1]);
    }
    void impl(int p, int v, int x, int l, int r) {
        if(l == r) {
            mx[x] += v;
            return;
        }
        int mid = (l+r)/2;
        if(mid >= p) impl(p, v, x*2, l, mid);
        else impl(p, v, x*2+1, mid+ 1, r);
        mx[x] = max(mx[x*2], mx[x*2+1]);
    }
    int get(int p, int q, int x, int l, int r) {
        if(l > q || r < p) return numeric_limits::min();
        if(l >= p && r <= q) return mx[x];
        int mid = (l+r)/2;
        return max(get(p, q, x*2, l, mid), get(p, q, x*2+1, mid+1, r));
    }
    void add(int p, int v) { impl(_l[p], v, 1, 1, n); }
    int operator()(const int x) { return get(_l[x], _r[x], 1, 1, n); }
} segs[THRESHOLD+1];
signed main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    fors(i, 1, n) cin >> a[i];
    fors(i, 1, THRESHOLD) segs[i].decl(i), segs[i].build(1, 1, n);
    cin >> m;
    for(int o, x, d; m--;) {
        cin >> o >> x >> d;
        if(o == 0) {
            a[x] += d;
            fors(i, 1, THRESHOLD) segs[i].add(x, d);
        } else {
            if(d > THRESHOLD) {
                int ans = numeric_limits::min();
                for(int i = x; i <= n; i += d) cmax(ans, a[i]);
                cout << ans << "n";
            } else cout << segs[d](x) << "n";
        }
    }
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/744518.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号