理解
莫队算法就是通过改变询问的顺序来减少时间复杂度。
把数组分成了
s
q
r
t
(
n
)
sqrt(n)
sqrt(n)块,根据块来处理问题。
板子
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<ctime>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<iomanip>
#include<list>
#include<bitset>
#include<sstream>
#include<fstream>
#include<complex>
#include<algorithm>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define int long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 1e9+7;
int cnt[100010],ans[100010],a[100010],res;
bool vis[100010];
struct sut{
int l,r,k;
}d[100010];
int apart;
bool cmp(sut a,sut b){
return (a.l/apart==b.l/apart)?a.r<b.r:a.l<b.l;
}
void add(int x){
res+=(cnt[a[x]]<<1)+1;
cnt[a[x]]++;
}
void sub(int x){
res-=(cnt[a[x]]<<1)-1;
cnt[a[x]]--;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++) cin>>a[i];
apart=sqrt(n);
for(int i=1;i<=m;i++){
cin>>d[i].l>>d[i].r;
d[i].k=i;
}
sort(d+1,d+1+m,cmp);
int cl=1,cr=0;
for(int i=1;i<=m;i++){
int l=d[i].l,r=d[i].r;
while(cl<l){
sub(cl++);
}
while(cl>l){
add(--cl);
}
while(cr<r){
add(++cr);
}
while(cr>r){
sub(cr--);
}
ans[d[i].k]=res;
}
for(int i=1;i<=m;i++){
cout<<ans[i]<<endl;
}
return 0;
}