제출 #1328960

#제출 시각아이디문제언어결과실행 시간메모리
1328960sitingfakeSterilizing Spray (JOI15_sterilizing)C++20
20 / 100
4341 ms1876 KiB
#include<bits/stdc++.h>
using namespace std;

#define ll long long

const int maxn = 1e5 + 7;
int n , k , q;
int a[maxn];
ll val[40];
ll SumMod[400][60] , Sum[400];

int L[450] , R[450] , id[maxn];
int Flag[450];
int lim = 0;
int BlockSize;

void Build(){
    BlockSize = max(1, (int)sqrt(n));
    val[0] = 1;
    const ll MAXA = 1000000000LL;
    bool br = false;
    for(int i = 1; i <= 35; i++){
        val[i] = val[i - 1] * 1ll * k;
        if(val[i] > MAXA){
            lim = i - 1;
            br = true;
            break;
        }
    }
    if(!br) lim = 35;
    if(k == 1) lim = 0;

    int numBlocks = (n + BlockSize - 1) / BlockSize;
    for(int b = 1; b <= numBlocks; ++b){
        L[b] = 0; R[b] = 0; Sum[b] = 0;
        Flag[b] = 0;
        for(int j = 0; j <= lim; ++j) SumMod[b][j] = 0;
    }

    for(int i = 1; i <= n; i++){
        id[i] = (i + BlockSize - 1) / BlockSize;
        int b = id[i];
        R[b] = i;
        if(L[b] == 0) L[b] = i;
        Sum[b] += a[i];
        for(int j = 0; j <= lim; j++){
            SumMod[b][j] += (a[i] % val[j]);
        }
        Flag[b] = 0;
    }
}

void Apply(int pos){
    if(Flag[pos] == 0) return;
    int f = Flag[pos];
    // reset
    Sum[pos] = 0;
    for(int j = 0; j <= lim; j++) SumMod[pos][j] = 0;
    // apply lazy to each element and rebuild Sum and SumMod
    for(int i = L[pos]; i <= R[pos]; i++){
        a[i] /= val[f];
        Sum[pos] += a[i];
        for(int j = 0; j <= lim; j++){
            SumMod[pos][j] += (a[i] % val[j]);
        }
    }
    Flag[pos] = 0;
}

void UpdatePos(int pos , int x){
    Apply(id[pos]);
    int b = id[pos];
    Sum[b] -= a[pos];
    Sum[b] += x;
    for(int i = 0; i <= lim; i++){
        SumMod[b][i] -= (a[pos] % val[i]);
        SumMod[b][i] += (x % val[i]);
    }
    a[pos] = x;
}
void UpdateRange(int l , int r){
    if(id[l] == id[r]){
        Apply(id[l]);
        int b = id[l];
        for(int i = l; i <= r; i++){
            if(a[i] == 0) continue;
            Sum[b] -= a[i];
            Sum[b] += (a[i] / k);
            for(int j = 0; j <= lim; j++){
                SumMod[b][j] -= (a[i] % val[j]);
                SumMod[b][j] += ((a[i] / k) % val[j]);
            }
            a[i] /= k;
        }
        return;
    }
    for(int i = id[l] + 1; i < id[r]; i++){
        Flag[i]++;
        if(Flag[i] > lim) Flag[i] = lim;
    }
    Apply(id[l]);
    Apply(id[r]);

    int bl = id[l], br = id[r];
    for(int i = l; i <= R[bl]; i++){
        if(a[i] == 0) continue;
        Sum[bl] -= a[i];
        Sum[bl] += (a[i] / k);
        for(int j = 0; j <= lim; j++){
            SumMod[bl][j] -= (a[i] % val[j]);
            SumMod[bl][j] += ((a[i] / k) % val[j]);
        }
        a[i] /= k;
    }

    for(int i = r; i >= L[br]; i--){
        if(a[i] == 0) continue;
        Sum[br] -= a[i];
        Sum[br] += (a[i] / k);
        for(int j = 0; j <= lim; j++){
            SumMod[br][j] -= (a[i] % val[j]);
            SumMod[br][j] += ((a[i] / k) % val[j]);
        }
        a[i] /= k;
    }
}

void QueryRange(int l , int r){
    ll ans = 0;
    if(id[l] == id[r]){
        Apply(id[l]);
        for(int i = l ; i <= r; i++) ans += a[i];
        cout << ans << "\n";
        return;
    }
    for(int i = id[l] + 1; i < id[r]; i++){
        int f = Flag[i];
        // sum floor(a_i / val[f]) for block i
        ans += ((Sum[i] / val[f]) - (SumMod[i][f] / val[f]));
    }
    Apply(id[l]);
    Apply(id[r]);
    for(int i = l; i <= R[id[l]]; i++) ans += a[i];
    for(int i = r ; i >= L[id[r]]; i--) ans += a[i];
    cout << ans << "\n";
}

void solve(void){
    cin >> n >> q >> k;
    for(int i = 1; i <= n; i++) cin >> a[i];
    Build();
    while(q--){
        int t , l , r;
        cin >> t >> l >> r;
        if(t == 1){
            UpdatePos(l , r);
        }
        else if(t == 2){
            UpdateRange(l , r);
        }
        else{
            QueryRange(l , r);
        }
    }
}

signed main(){
   ios_base::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
   //freopen("gray.inp" , "r" , stdin);
   //freopen("gray.out" , "w" , stdout);
   solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...