「一本通 4.3 练习 2」花神游历各国(loj10128)

Posted junk-yao-blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「一本通 4.3 练习 2」花神游历各国(loj10128)相关的知识,希望对你有一定的参考价值。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 1000010;
inline void qread(int &x){
    x = 0;
    register int ch = getchar(), flag = 0;
    while(ch < ‘0‘ || ch > ‘9‘)    {
        if(ch == ‘-‘)    flag = 1;
        ch =getchar();
    }
    while(ch >=‘0‘ && ch <=‘9‘){
        x = 10 * x + ch - 48;
        ch = getchar();
    }
    if(flag)    x = -x;
}
const int maxsqr = 5;
int n, q;
int *data;
int *sum;
int *sqr;
inline void update(const int &x){
    sum[x] = sum[x << 1] + sum[x << 1 | 1];
}
void pushdown(int x){
    sqr[x << 1] += sqr[x];
    sqr[x << 1 | 1] += sqr[x];
    sqr[x] = 0;
}
void build(int l, int r, int x){
    if(l == r){
        sum[x] = data[l];
        return ;
    }
    int mid = (l + r) >> 1;
    build(l, mid, x << 1);
    build(mid + 1, r, x << 1 | 1);
    update(x);
}
void add(int l, int r, int L, int R, int x){
    if(l == r){
        sqr[x]++;
        while(sqr[x]--)
            sum[x] = floor(sqrt(sum[x]));
        sqr[x]++;    
        return ;
    }
    if(L <= l && R >= r){
        sqr[x]++;
        return ;
    }
    pushdown(x);
    int mid = (l + r) >> 1;
    if(R > mid)                add(mid + 1, r, L, R, x << 1 | 1);
    if(L <= mid)              add(l, mid, L, R, x << 1);
    update(x);
}
int ask(int l, int r, int L, int R, int x){
    if(l == r){
        while(sqr[x]--)
            sum[x] = floor(sqrt(sum[x]));
        sqr[x]++;    
        return sum[x];    
    }
    if(L <= l && R >= r && sqr[x] >= 5)
            return r - l + 1;
    pushdown(x);    
    int mid = (l + r) >> 1;
    int ans = 0;
    if(L <= mid)    ans += ask(l, mid, L, R, x << 1);
    if(R > mid)     ans += ask(mid + 1, r, L, R, x << 1 | 1);
    update(x);
    return ans;
}
void init(){
    qread(n);
    sum = new int[n << 2];
    data = new int[n << 2];
    sqr = new int[n << 2];
    memset(sqr, 0, (n << 2) * sizeof(int));
    for(int i=1; i<=n; ++i)    qread(data[i]);
    build(1, n, 1);
    qread(q);
}                          
int main(void) {
    init();
    while(q--){
        int op, l, r;
        qread(op), qread(l), qread(r);
        if(op == 1)
            printf("%d ", ask(1, n, l, r, 1));
        else
            add(1, n, l, r, 1);   
    }

}





































































































以上是关于「一本通 4.3 练习 2」花神游历各国(loj10128)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3211 花神游历各国 线段树,势能分析

BZOJ 3211 花神游历各国 线段树题解

BZOJ 3211: 花神游历各国

BZOJ3211: 花神游历各国

bzoj3211花神游历各国 线段树

P4145 上帝造题的七分钟2 / 花神游历各国