花神遊歷各國

當時在火車上思考的, 思考了半天突然發現了開方操作不是平方操作, 開多了就成1了

然後我發現這樣就可以暴力的去做了, 因爲整個數列最多開6次, 之後就都成了1.

我特別發現數列是沒有零的, 如果沒有0值的話, 一個區間的和如果等於他的長度, 就不需要開深入修改了。

洛谷P4145的數據是沒有零的, libreOj的信息學奧賽一本通提高篇的練習題是有零的。

今天交了幾次, 但是都不對, 我發現數列是有零的, 然後我就有點蒙了。才發現在維護一個區間最大值就可以了。

但還是不對, 最後在一組樣例的幫助下, 我把不再查詢的區間最先return即可。

// 要注意一個區間與另一個區間的關係有三種, 完全包含, 完全不想交, 完全不包含
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
const int MAXN = 1e5 + 600;
typedef long long ll;
using namespace std;
int n, m;
int cmd, ql, qh;
struct Segment{
    ll sum, max;
} s[MAXN << 2 | 1];
inline void update(int o){
    s[o].sum = s[o << 1].sum + s[o << 1 | 1].sum;
    s[o].max = max(s[o << 1].max, s[o << 1 | 1].max);
}
void build(int o, int lo ,int hi){
    if(hi - lo < 2){
        scanf("%lld", &s[o].sum);
        s[o].max = s[o].sum;
        return;
    }

    int mi = (lo + hi) >> 1;
    build(o << 1, lo, mi);
    build(o << 1 | 1, mi, hi);

    update(o);
}
void modify(int o, int lo, int hi){
    if(qh <= lo || hi <= ql){// 最先判斷
        return;
    }
    if(hi - lo < 2){
        s[o].sum = (ll)(floor(sqrt(s[o].sum)));
        s[o].max = s[o].sum;
        return;
    }
    if(ql <= lo && hi <= qh){
        if(s[o].max < 2){
            return;
        }
    }

    int mi = (lo + hi) >> 1;
    modify(o << 1, lo, mi);
    modify(o << 1 | 1, mi, hi);

    update(o);
}
ll query(int o, int lo, int hi){
    if(ql <= lo && hi <= qh){
        return s[o].sum;
    }
    if(qh <= lo || hi <= ql){
        return 0;
    }
    int mi = (lo + hi) >> 1;
    ll rst = query(o << 1, lo, mi) + query(o << 1 | 1, mi, hi);

    return rst;
}
void print(int o, int lo, int hi){
    if(hi - lo < 2){
        printf(" %lld", s[o].sum);
        return;
    }
    int mi = (lo + hi) >> 1;
    print(o << 1, lo, mi);
    print(o << 1 | 1, mi, hi);
}
int main(){
    scanf("%d", &n);
    build(1, 1, ++n);
    scanf("%d", &m);
    // print(1, 1, n); puts("\tOUT");
    while(m--){
        scanf("%d%d%d", &cmd, &ql, &qh);
        if(ql > qh){
            swap(ql, qh);
        }
        ++qh;
        if(cmd == 1){
            printf("%lld\n", query(1, 1, n));
        }
        else{
            modify(1, 1, n);
        }
        // print(1, 1, n); puts("\tOUT");
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章