RT,代码如下。自我感觉排序有问题(所以我查找了另一种排序方式,见注释),但是不知道有什么问题。
#include<bits/stdc++.h>
using namespace std;
const int N=5e4+5;
int n,m,k,a[N];
struct ask{
int l,r,id;
}s[N];
/*
博客中该函数就等于在块外先按左端点排序,块内再按右端点排序
bool cmp(query a, query b)
{
return (a.l/bl) == (b.l/bl) ? a.r < b.r : a.l < b.l;
}
*/
int blen,btot,cnt[N];
inline int L(int block) {
if(block==1) return 1;
else return (block-1)*blen+1;
}
inline int R(int block) {
if(block==btot) return n;
else return block*blen;
}
inline int where(int idx) {
return (idx-1)/blen+1;
}
bool build(){
cin>>n>>m>>k;
blen=sqrt(n);
btot=(n/blen)+(n%blen?1:0);
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=m;i++){
cin>>s[i].l>>s[i].r;
s[i].id=i;
}
}
bool cmpA(ask a,ask b){
return a.l<b.l;
}
bool cmpP(ask a,ask b){
return a.r<b.r;
}
long long out[N],ans;
void work(int x,int c){
ans+=2*cnt[x]*c+c*c;
cnt[x]+=c;
}
int main(){
build();
sort(s+1,s+1+n,cmpA);
for(int i=1;i<=btot;i++){
sort(s+L(i),s+1+R(i),cmpP);
}
int l=1,r=0;
for(int i=1;i<=n;i++){
while(l>s[i].l) l--,work(a[l],1);
while(r<s[i].r) r++,work(a[r],1);
while(l<s[i].l) work(a[l],-1),l++;
while(r>s[i].r) work(a[r],-1),r--;
out[s[i].id]=ans;
}
for(int i=1;i<=m;i++){
cout<<out[i]<<endl;
}
return 0;
}
记录:
所有代码都是一份,大佬们可以自行fc验证。
十分感谢您的帮助。