zoukankan      html  css  js  c++  java
  • LOJ6281. 数列分块入门 5 题解

    题目链接:https://loj.ac/p/6281

    涉及操作:

    1. 区间开方;
    2. 区间求和。

    解题思路:

    主要思路:(2^{32}) 次方内的数最多开 (7) 次方都会变成 (1)

    (tag_i) 表示第 (i) 个分块的整体开方次数,则 (tag_i ge 7) 时这个分块中的所有元素都为 (1)

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 50050;
    int n, blo, bl[maxn], a[maxn], sum[505], tag[505];
    
    /**
    tag[i]记录第i个分块的数值和
    sum[i]第i个块所有单独增加的元素和
    */
    
    void kaifang(int l, int r) {
        for (int i = l; i <= min(bl[l]*blo, r); i ++) {
            sum[bl[i]] -= a[i];
            a[i] = sqrt(a[i]);
            sum[bl[i]] += a[i];
        }
        if (bl[l] != bl[r]) {
            for (int i = (bl[r]-1)*blo+1; i <= r; i ++) {
                sum[bl[i]] -= a[i];
                a[i] = sqrt(a[i]);
                sum[bl[i]] += a[i];
            }
        }
        for (int i = bl[l]+1; i < bl[r]; i ++) {
            tag[i] ++;
            if (tag[i] < 7) {
                for (int j = (i-1)*blo+1; j <= i*blo; j ++) {
                    sum[bl[j]] -= a[j];
                    a[j] = sqrt(a[j]);
                    sum[bl[j]] += a[j];
                }
            }
        }
    }
    
    int query(int l, int r) {
        int ans = 0;
        for (int i = l; i <= min(bl[l]*blo, r); i ++)
            ans += a[i];
        if (bl[l] != bl[r])
            for (int i = (bl[r]-1)*blo+1; i <= r; i ++)
                ans += a[i];
        for (int i = bl[l]+1; i < bl[r]; i ++)
            ans += sum[i];
        return ans;
    }
    
    int main() {
        ios::sync_with_stdio(0);
        cin >> n;
        blo = sqrt(n);
        for (int i = 1; i <= n; i ++) {
            cin >> a[i];
            bl[i] = (i - 1) / blo + 1;
            sum[bl[i]] += a[i];
        }
        for (int i = 0; i < n; i ++) {
            int op, l, r, c;
            cin >> op >> l >> r >> c;
            if (op == 0) kaifang(l, r);
            else cout << query(l, r) << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    寻找回文数
    【C/C++语言入门篇】 位运算
    怎样判断输入是否结束
    命名那个数字
    Broken Necklace
    C#打造邮件接受器VS2005版
    C#应用程序打包时自动安装MSDE
    SQL6.5到2005发布的版本号搜集整理
    SQL无限分类存储过程整理2
    ASP.NET调用SWF代码文件
  • 原文地址:https://www.cnblogs.com/quanjun/p/15525589.html
Copyright © 2011-2022 走看看