https://codeforc.es/contest/86/problem/D
题意:
问一些区间[l,r]内所有至少一次的数字*该数字的出现次数^2之和
题解:
裸题,复习一下莫队,
根号算法果然很慢..2e5跑了2.5s
#include <bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define fi first
#define se second
#define mp make_pair
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(ii,a,b) for(int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(int ii=b;ii>=a;--ii)
using namespace std;
const int maxn=2e6+10,maxm=2e6+10;
int casn,n,m,k;
ll a[maxn],ans[maxn],sz,sum;
class block{public:
ll cnt[maxn];
struct node{
ll l,r,id;
bool operator <(const node &b)const {
if(l/sz!=b.l/sz) return l<b.l;
if((l/sz)&1) return r<b.r;
return r>b.r;
}
};
void update(int pos,ll flag=1){
sum+=flag*a[pos]*(cnt[a[pos]]*2ll+flag);
cnt[a[pos]]+=flag;
}
}ask;
vector<block::node> tab;
int main() {
IO;
cin>>n>>m;sz=sqrt(n);
rep(i,1,n) cin>>a[i];
rep(i,1,m) {
int a,b;cin>>a>>b;
tab.push_back({a,b,i});
}
sort(all(tab));
int l=tab[0].l,r=tab[0].l-1;
for(auto now:tab){
while(l>now.l) ask.update(--l,1);
while(l<now.l) ask.update(l++,-1);
while(r<now.r) ask.update(++r,1);
while(r>now.r) ask.update(r--,-1);
ans[now.id]=sum;
}
rep(i,1,m) cout<<ans[i]<<endl;
return 0;
}