• BZOJ3211 花神游历各国(分块 区间开根号)


    题意:给n个数,可以进行两种操作:给区间[l,r]每个数开方向下取整;算区间[l,r]的和。

    思路:我们可以知道,一个数一直开方下去,就会变成0或者1,然后就不会变了。那么当一个区间只剩0或1时,就不用进行操作了。那么直接分块,然后搞一个flag判断一下是否变成0。稍微优化一下。

    代码:

    #include<cmath>
    #include<set>
    #include<map>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include <iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 1e5 + 10;
    const int M = maxn * 30;
    const ull seed = 131;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    int belong[maxn], block;
    int flag[maxn];
    ll sum[maxn];
    ll a[maxn];
    struct Block{
        int l, r;
    }b[maxn];
    void change(int l, int r){
        int bl = belong[l], br = belong[r];
        if(bl == br){
            if(!flag[bl]){
                for(int i = l; i <= r; i++){
                    sum[bl] -= a[i];
                    a[i] = (int)sqrt(a[i]);
                    sum[bl] += a[i];
                }
                flag[bl] = 1;
                for(int j = b[bl].l; j <= b[bl].r; j++){
                    if(a[j] > 1){
                        flag[bl] = 0;
                        break;
                    }
                }
            }
        }
        else{
            if(!flag[bl]){
                for(int i = l; i <= b[bl].r; i++){
                    sum[bl] -= a[i];
                    a[i] = (int)sqrt(a[i]);
                    sum[bl] += a[i];
                }
                flag[bl] = 1;
                for(int j = b[bl].l; j <= b[bl].r; j++){
                    if(a[j] > 1){
                        flag[bl] = 0;
                        break;
                    }
                }
            }
            for(int i = bl + 1; i <= br - 1; i++){
                if(!flag[i]){
                    sum[i] = 0;
                    flag[i] = 1;
                    for(int j = b[i].l; j <= b[i].r; j++){
                        a[j] = (int)sqrt(a[j]);
                        sum[i] += a[j];
                        if(a[j] > 1) flag[i] = 0;
                    }
                }
            }
            if(!flag[br]){
                for(int i = b[br].l; i <= r; i++){
                    sum[br] -= a[i];
                    a[i] = (int)sqrt(a[i]);
                    sum[br] += a[i];
                }
                flag[br] = 1;
                for(int j = b[br].l; j <= b[br].r; j++){
                    if(a[j] > 1){
                        flag[br] = 0;
                        break;
                    }
                }
            }
        }
    }
    
    ll query(int l, int r){
        int bl = belong[l], br = belong[r];
        ll ans = 0;
        if(bl == br){
            for(int i = l; i <= r; i++){
                ans += a[i];
            }
        }
        else{
            for(int i = l; i <= b[bl].r; i++){
                ans += a[i];
            }
            for(int i = bl + 1; i <= br - 1; i++){
                ans += sum[i];
            }
            for(int i = b[br].l; i <= r; i++){
                ans += a[i];
            }
        }
        return ans;
    }
    int main(){
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i++){
            scanf("%lld", &a[i]);
        }
        block = sqrt(n);
        for(int i = 1; i <= n; i++){
            belong[i] = (i - 1) / block + 1;
        }
        for(int i = 1; i <= belong[n]; i++){
            b[i].l = (i - 1) * block + 1;
            b[i].r = min(n, b[i].l + block - 1);
            sum[i] = flag[i] = 0;
            for(int j = b[i].l; j <= b[i].r; j++) sum[i] += a[j];
        }
        int m;
        scanf("%d", &m);
        for(int i = 1; i <= m; i++){
            int o, l, r;
            int c;
            scanf("%d%d%d", &o, &l, &r);
            if(o == 2){
                change(l, r);
            }
            else{
                printf("%lld
    ", query(l, r));
            }
        }
        return 0;
    }
  • 相关阅读:
    没有精神分裂的测试不是一个好家长
    防火墙中配置开放 8080端口--续上一篇
    rocketMQ(一)基础环境
    如何做一个对账系统
    通用对账系统介绍与设计(上)
    pdf转图片
    虚拟机加载类机制
    jenkins
    zookeeper和dubbo
    正则日常积累
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10903409.html
Copyright © 2020-2023  润新知