zoukankan      html  css  js  c++  java
  • SPOJ2713GSS4

    题意

    Sol

    讲过无数次了。。很显然,一个$10^12$的数开方不超过$8$次后就会变为$1$

    因此直接暴力更改即可,维护一下这段区间是否被全改为了$1$

    双倍经验:https://www.luogu.org/problemnew/show/P4145

    #include<cstdio>
    #include<algorithm>
    #include<stack>
    #include<queue>
    #include<cmath>
    #define int long long 
    #define Pair pair<int, int> 
    #define fi first
    #define se second
    #define MP(x, y) make_pair(x, y)
    using namespace std;
    const int MAXN = 1e6 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); 
        return x * f;
    }
    int N, M;
    int a[MAXN];
    #define ls k << 1
    #define rs k << 1 | 1
    struct Node {
        int l, r, w, f;
    }T[MAXN];
    void update(int k) {
        if(T[ls].f && T[rs].f) T[k].f = 1;
        T[k].w = T[ls].w + T[rs].w;    
    }
    void Build(int k, int ll, int rr) {
        T[k] = (Node) {ll, rr};
        if(ll == rr) {
            T[k].w = a[ll];
            return ;
        }
        int mid = ll + rr >> 1;
        Build(ls, ll, mid);
        Build(rs, mid + 1, rr);
        update(k);
    }
    void push(int k) {
        if(T[k].f) return ;
        if(T[k].l == T[k].r) {
            T[k].w = sqrt(T[k].w); 
            if(T[k].w == 1) T[k].f = 1;
            return ;
        }
        push(ls); push(rs);
        update(k);
    }
    void IntSqrt(int k, int ll, int rr) {
        if(ll <= T[k].l && T[k].r <= rr) {
            if(T[k].f) return ;
            push(k); return ;
        }
        int mid = T[k].l + T[k].r >> 1;
        if(ll <= mid) IntSqrt(ls, ll, rr);
        if(rr >  mid) IntSqrt(rs, ll, rr);
        update(k);
    }
    int IntSum(int k, int ll, int rr) {
        if(ll <= T[k].l && T[k].r <= rr) return T[k].w;
        int mid = T[k].l + T[k].r >> 1;
        if(ll > mid) return IntSum(rs, ll, rr);
        else if(rr <= mid) return IntSum(ls, ll, rr);
        else return IntSum(ls, ll, rr) + IntSum(rs, ll, rr);
    }
    main() {
        int tot = 0;
        while(scanf("%d", &N) != EOF) {
            printf("Case #%d:
    ", ++tot);
            for(int i = 1; i <= N; i++) a[i] = read();
            Build(1, 1, N);
            M = read();
            while(M--) {
                int k = read(), l = read(), r = read();
                if(l > r) swap(l, r);
                if(k == 0) IntSqrt(1, l, r);
                else printf("%lld
    ", IntSum(1, l, r));
            }
            puts("");
        }
    
        return 0;
    }
    /*
    
    */
  • 相关阅读:
    逻辑分支
    iOS开发——NSArray中的字符串排序
    iOS开发——实时监控网速(仅作参考,发现一点问题)
    iOS10适配——相机,通讯录,麦克风等权限设置
    iOS10适配——Push Notifications
    iOS开发——获取当前屏幕显示的viewcontroller
    iOS开发——应用图标上显示消息数量
    iOS开发——获取手机当前WiFi名和MAC地址
    我是一个线程(写的太好了,忍不住转过来)
    iOS开发——WAVE音频文件解析
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9572678.html
Copyright © 2011-2022 走看看