zoukankan      html  css  js  c++  java
  • 洛谷P4145 上帝造题的七分钟2 / 花神游历各国 题解 线段树+懒惰标记

    题目链接:https://www.luogu.com.cn/problem/P4145

    题目大意:

    两种操作:

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

    解题思路:

    使用线段树解决这个问题。

    但是区间更新(开方)需要懒惰标记。

    但是这样也会TLE,所以还需要记录区间更新的次数的最小值,如果这个区间内的每个数都开方达到6次,那么这个区间内的数就都是1了。

    实现代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 100010;
    int n, m;
    long long sum[maxn<<2];
    int lazy[maxn<<2], upd_times[maxn<<2];
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    void push_up(int rt) {
        sum[rt] = sum[rt<<1] + sum[rt<<1|1];
        upd_times[rt] = min(upd_times[rt<<1], upd_times[rt<<1|1]);
    }
    void push_down(int rt, int l, int r) {
        if (lazy[rt]) {
            if (l < r) {
                lazy[rt<<1] += lazy[rt];
                lazy[rt<<1|1] += lazy[rt];
            }
            else {
                for (int i = 0; i < lazy[rt] && sum[rt] > 1; i ++)
                    sum[rt] = sqrt(sum[rt]);
            }
            upd_times[rt] += lazy[rt];
        }
        lazy[rt] = 0;
    }
    void build(int l, int r, int rt) {
        if (l == r) {
            scanf("%lld", &sum[rt]);
        }
        else {
            int mid = (l + r) / 2;
            build(lson);
            build(rson);
            push_up(rt);
        }
    }
    void update(int L, int R, int l, int r, int rt) {
        if (L <= l && r <= R) {
            lazy[rt] ++;
            return;
        }
        push_down(rt, l, r);
        if (upd_times[rt] > 6) return;
        int mid = (l + r) / 2;
        if (L <= mid) update(L, R, lson);
        if (R > mid) update(L, R, rson);
        push_up(rt);
    }
    long long query(int L, int R, int l, int r, int rt) {
        push_down(rt, l, r);
        if (L <= l && r <= R && upd_times[rt] > 6) return r-l+1;
        if (l == r) return sum[rt];
        long long tmp = 0;
        int mid = (l + r) / 2;
        if (L <= mid) tmp += query(L, R, lson);
        if (R > mid) tmp += query(L, R, rson);
        push_up(rt);
        return tmp;
    }
    int main() {
        scanf("%d", &n);
        build(1, n, 1);
        scanf("%d", &m);
        while (m --) {
            int op, l, r;
            scanf("%d%d%d", &op, &l, &r);
            if (l > r) swap(l, r);
            if (op == 0) {
                update(l, r, 1, n, 1);
            }
            else {
                printf("%lld
    ", query(l, r, 1, n, 1));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    做好最后的1%
    南海城市大脑二期测试的思考
    职场动物进化手册
    搜索框测试用例
    三月版三一金票需求测试总结
    “魔鬼”隐藏在细节中
    java----jdbcTemplate
    内网隧道与SOCKS代理思路总结
    一些免杀方法测试
    JavaScript 关于闭包、同步、异步问题
  • 原文地址:https://www.cnblogs.com/quanjun/p/12345453.html
Copyright © 2011-2022 走看看