SST

sum-SST, change for other operations accordingly.
 avatar
unknown
c_cpp
7 months ago
1.6 kB
39
Indexable
//keep in mind that the indexing is always 1-based inside of the structure so do the querying accordingly.
//If u spot some bug, then its in the way you query, because I have stress-tested the below version for any bugs.
#include<bits/stdc++.h>

using namespace std;
#define int long long
using ll = long long;

int log(int x) {
    return 32 - __builtin_clz(x) - 1;
}

int logll(ll x){
	return 64 - __builtin_clzll(x) - 1;
}

struct SST{
	int N, LOG, p = 1, jump = 1;
	vector<vector<ll>>S;
	SST(const vector<ll>&A){
		//Building the SST
		N = A.size() - 1;
		LOG = logll(N + 1) + 1;
		S.resize(N + 1);
		for(int i = 1 ; i <= N ; i++){
			S[i].resize(__builtin_ctz(i) + 1);
			S[i][0] = A[i];
		}
		while(jump <= N){
        jump <<= 1;
        for(int i = jump ; i <= N ; i += jump){
            S[i][p] = S[i][p - 1] + S[i - (jump >> 1)][p - 1];
        }
        p++;
 	   }
	}
	
	void update(int index, ll value){
		 int p = 1;
		 S[index][0] = value;
		 if(S[index].size() == 1){
		 	index += 1;
		 }
	    while(index <= N){
	 		 S[index][p] = S[index][p - 1] + S[index - (1 << (p - 1))][p - 1];
	 		 ++p;
	 		 if(p == S[index].size()){
	 			 index += (1ll << (p - 1));
	 		 }
		  }
	   }
	ll query(int L, int R){
		int answer = 0, d, p, i;
		while(R >= L && (R - (1ll << (S[R].size() - 1)) > L - 2)){
			answer += S[R].back();
			R -= (1ll << (S[R].size() - 1));
		}
		if(R < L){
			return answer;
		}
		d = R - L + 1;
		p = logll(d + 1);
		for(i = p ; i >= 0 ; i--){
			if((1ll << i)&d){
				answer += S[R][i];
				R -= (1ll << i);
			}
		}
		return answer;
	}
};
Editor is loading...
Leave a Comment