「分塊系列」數列分塊入門5 解題報告

數列分塊入門5

題意歸納

區間開方,區間求和。html

寫在前面

這題須要更好地利用暴力QAQ 不暴力這題簡直無法作~c++

還有注意下,因爲不是同一時段的代碼,所屬分塊以後都寫成b而不是p了QAQ 但願諒解。數組

正題

由於每一個數都不超過2 ^ 31 - 1,因此一個數開方5次,確定會爲1。spa

咱們能夠對這一性質加以利用 好好暴力QAQ。code

咱們用一個數組v來記錄當前塊是否全爲1,s記錄這一塊的和。當修改時,若該塊全爲1,就用不着更新了;若是不是,就暴力一次,直接把這塊全開方了(別忘了更新s),順便判斷是否全爲1,對v進行更新。對於兩邊不完整塊,仍是老樣子——暴力QAQ。htm

時間複雜度分析

咱們把修改完整塊和不完整塊分開分析。blog

對於完整塊,最多修改5次,由於前面分析過,修改5次確定都爲1了,因此上限爲O(5n)。get

對於不完整塊,每次修改最多觸及2次,因此上限爲O(2n√n) 期間枚舉完整塊時間上限爲O(n√n)。it

最後加起來就是O(5n+3n√n) 知足複雜度要求。入門

代碼

#include<bits/stdc++.h>
using namespace std;
#define MAXN 50005

int a[MAXN], s[300], b[MAXN];
bool v[300]; 
int n, d;

void modify( int x, int y ){
    if ( b[x] == b[y] ){
        for ( int i = x; i <= y; ++i ){
            s[b[x]] -= a[i]; a[i] = sqrt(a[i]); s[b[x]] += a[i];
        }
        return;
    }
    for ( int i = x; b[i] == b[x]; ++i ){
        s[b[x]] -= a[i]; a[i] = sqrt(a[i]); s[b[x]] += a[i];
    }//修改不完整塊 更新 s 的值
    for ( int i = y; b[i] == b[y]; --i ){
        s[b[y]] -= a[i]; a[i] = sqrt(a[i]); s[b[y]] += a[i];
    }
    for ( int i = b[x] + 1; i <= b[y] - 1; ++i ){
        if ( !v[i] ){//知足全爲1就別作了 不知足才作
            v[i] = 1;
            for ( int j = d * ( i - 1 ) + 1; b[j] == i; ++j ){
                s[i] -= a[j]; a[j] = sqrt(a[j]); s[i] += a[j];
                if ( a[j] > 1 ) v[i] = 0;//仍是不知足QAQ
            }
        }
    }
}

int Get( int x, int y ){//很好理解 不解釋了
    int ans(0);
    if ( b[x] == b[y] ){
        for ( int i = x; i <= y; ++i ) ans += a[i];
        return ans;
    }
    for ( int i = x; b[i] == b[x]; ++i ) ans += a[i];
    for ( int i = y; b[i] == b[y]; --i ) ans += a[i];
    for ( int i = b[x] + 1; i <= b[y] - 1; ++i ) ans += s[i];
    return ans;
}

int main(){
    scanf( "%d", &n ); d = sqrt(n);
    for ( int i = 1; i <= n; ++i ){
        scanf( "%d", &a[i] ); b[i] = ( i - 1 ) / d + 1;
        s[b[i]] += a[i];
    }
    for ( int i = 1; i <= n; ++i ){
        int opt, l, r, c; scanf( "%d%d%d%d", &opt, &l, &r, &c );
        if ( opt ) printf( "%d\n", Get( l, r ) );
        else modify( l, r );
    }
    return 0;
}

數列分塊系列目錄

數列分塊入門1

數列分塊入門2

數列分塊入門3

數列分塊入門4

數列分塊入門5 <-

數列分塊入門6

數列分塊入門7

數列分塊入門8

數列分塊入門9

蒲公英

公主的朋友

相關文章
相關標籤/搜索