Sparse Table: Int Int L Int R Int
Sparse Table: Int Int L Int R Int
Mo’s Algorithm
const int mxN = 2e6+5;
const int mxM = 2e6+5;
int n, q, block;
ll ans[mxN] = {0};
ll a[mxN], cnt[mxM] = {0};
struct Queries{
int l, r;
int stt;
Queries(){
}
Queries(int l,int r,int stt){
this -> l = l;
this -> r = r;
this -> stt = stt;
}
};
bool cmp(Queries A, Queries B){
if(A.l / block != B.l / block){
return A.l < B.l;
}
else{
if((A.l/block) %2 == 1){
return A.r < B.r;
}
else return A.r > B.r;
}
}
vector<Queries> Q;
ll TruDi(int x){
ll S = 0;
S -= 1ll*cnt[x]*cnt[x]*x;
--cnt[x];
S += 1ll*cnt[x]*cnt[x]*x;
return S;
}
ll CongVo(int x){
ll S = 0;
S -= 1ll*cnt[x]*cnt[x]*x;
++cnt[x];
S += 1ll*cnt[x]*cnt[x]*x;
return S;
}
int main(){
cin>>n>>q;
for(int i = 1; i<=n;i ++) cin>>a[i];
block = max(1,(int)( n / sqrt(q))); //sqrt(n - 1) + 1;
Q.resize(q);
int o = 0;
for(auto &t : Q){
cin>>t.l>>t.r;
t.stt = o++;
}
sort(Q.begin(), Q.end(), cmp);
ll res = 0;
int curL = 1, curR = 0;
for(int i = 0; i<q; i++){
int l = Q[i].l;
int r = Q[i].r;
int stt = Q[i].stt;
while(curL < l)
res += TruDi(a[curL++]);
while(curL > l)
res += CongVo(a[--curL]);
while(curR > r)
res += TruDi(a[curR--]);
while(curR < r)
res += CongVo(a[++curR]);
ans[stt] = res;
}
for(int i = 0; i<q; i++) cout<<ans[i]<<endl;
return 0;
}
BIT
const int maxn = 100000;
ull A[maxn], bit[maxn];
int N, Q;
void add(int u, ull v) {
int idx = u;
while(idx <= N) {
bit[idx] += (ull)v;
idx += (idx) & (-idx);
}
}
ull getSum(int u) {
ull sum = 0;
while(u > 0) {
sum += bit[u];
u -= u & (-u);
}
return sum;
}
ull get_sum_on_segment(int l, int r) {
return getSum(r) - getSum(l - 1);
}
void solve1() {
int p;
ull x;
cin >> p >> x;
add(p, x);
}
void solve2() {
int u, v; cin >> u >> v;
cout << get_sum_on_segment(u, v) << endl;
}
void preprocess() {
bit[0] = 0;
for(int i = 1; i <= N; ++i) add(i, A[i - 1]);
}
Chia Căn
struct Sqrt {
int block_size;
vector<int> nums;
vector<unordered_map<int, int>> blocks;
Sqrt(int sqrtn, vector<int> &arr) : block_size(sqrtn), blocks(sqrtn) {
nums = arr;
for (int i = 0; i < nums.size(); i++) {
blocks[i / block_size][nums[i]]++;
}
}
void update(int x, int v) {
int block_idx = x / block_size;
blocks[block_idx][nums[x]]--;
if (blocks[block_idx][nums[x]] == 0) {
blocks[block_idx].erase(nums[x]);
}
nums[x] = v;
blocks[block_idx][v]++;
}
int query(int l, int r, int k) {
int blockL = (l + block_size - 1) / block_size;
int blockR = r / block_size;
int sum = 0;
return sum;
}
};