zoukankan      html  css  js  c++  java
  • HDU

    题目链接:Can you answer these queries?

    题意:维护一个序列,支持两种操作:(1)将区间[l,r]内的所有数开根号(向下取整),(2)求区间[l,r]内元素的和

    思路:和The Child and Sequence类似,对于操作(1),一个数最多开7次根号(向下取整)就会变为1,此时就不用再开根号了,所以我们用线段树维护区间和,如果一个区间和等于这个区间的长度,则表示这个区间内所有元素都为1,此时可以直接减枝,否则继续递归,直到叶子节点,然后开根号向下取整,其实也可以再维护一个区间最大值,如果最大值等于1,则可以直接减枝,对于操作(2),线段树区间查询区间和即可,注意可能有l>r,交换l,r即可

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 100010;
    
    struct node {
        int l, r;
        ll v;
    };
    
    int n, m, icas;
    node tr[4 * N];
    ll c[N];
    
    void build(int k, int l, int r)
    {
        tr[k].l = l, tr[k].r = r;
        if (l == r) {
            tr[k].v = c[l];
            return;
        }
        int mid = (l + r) / 2;
        build(2 * k, l, mid);
        build(2 * k + 1, mid + 1, r);
        tr[k].v = tr[2 * k].v + tr[2 * k + 1].v;
    }
    
    void update(int k, int a, int b)
    {
        if (tr[k].v == tr[k].r - tr[k].l + 1) return;
        if (tr[k].l == tr[k].r) {
            tr[k].v = sqrt(tr[k].v);
            return;
        }
        int mid = (tr[k].l + tr[k].r) / 2;
        if (a <= mid) update(2 * k, a, b);
        if (b > mid) update(2 * k + 1, a, b);
        tr[k].v = tr[2 * k].v + tr[2 * k + 1].v;
    }
    
    ll ask(int k, int a, int b)
    {
        if (tr[k].l >= a && tr[k].r <= b) return tr[k].v;
        int mid = (tr[k].l + tr[k].r) / 2;
        ll res = 0;
        if (a <= mid) res += ask(2 * k, a, b);
        if (b > mid) res += ask(2 * k + 1, a, b);
        return res;
    }
    
    int main()
    {
        while (scanf("%d", &n) != EOF) {
            for (int i = 1; i <= n; i++) scanf("%lld", &c[i]);
            build(1, 1, n);
            scanf("%d", &m);
            printf("Case #%d:
    ", ++icas);
            while (m--) {
                int op, a, b;
                scanf("%d%d%d", &op, &a, &b);
                if (a > b) swap(a, b);
                if (0 == op) update(1, a, b);
                else printf("%lld
    ", ask(1, a, b));
            }
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    CSS浮动(float、clear)通俗讲解
    JAVA 类的加载
    数据库操作 delete和truncate的区别
    正则表达式 匹配相同数字
    Oracle EBS OM 取消订单
    Oracle EBS OM 取消订单行
    Oracle EBS OM 已存在的OM订单增加物料
    Oracle EBS OM 创建订单
    Oracle EBS INV 创建物料搬运单头
    Oracle EBS INV 创建物料搬运单
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12774040.html
Copyright © 2011-2022 走看看