莫队算法
#bzoj2038 ##600ms ##小Z的袜子 ##优化过后的代码,效果强劲……

$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$
```c++
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<set>
#include<queue>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<stack>
#define rez(i,x,y) for(int i=x;i>=y;i--)
#define res(i,x,y) for(int i=x;i<=y;i++)
#define INF 2100000000
#define ll long long
#define clr(x) memset(x,0,sizeof(x))
using namespace std;
const int maxn = 50000 + 50;
templateinline void readin(T &res){
static char ch;
while ((ch = getchar()) < '0' || ch > '9');
res = ch - 48;
while ((ch = getchar()) >= '0' && ch <= '9')
res = res * 10 + ch - 48;
}
int n,m,unity,num[maxn],a[maxn],tot,L=1,R=0;;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
struct Query{
int l,r,pos;
bool operator < (const Query &rhs)const{
return (l/unity!=rhs.l/unity)?(l/unity<rhs.l/unity):(r<rhs.r);
}
}node[maxn];
struct Ans{
ll a,b;
void reduce(){
ll dv=gcd(a,b);
a/=dv,b/=dv;
}
}ans[maxn];
int main(){
freopen("in.txt","r",stdin);
readin(n),readin(m);
unity=(int)sqrt(n);
memset(num,0,sizeof(num));
for(int i=1;i<=n;i++)
readin(a[i]);
for(int i=1;i<=m;i++)
readin(node[i].l),readin(node[i].r),node[i].pos=i;
sort(node+1,node+1+m);
for(int i=1;i<=m;i++){
while(R<node[i].r){
++R;
tot+=num[a[R]]*2+1;
++num[a[R]];
}
while(R>node[i].r){
--num[a[R]];
tot-=num[a[R]]*2+1;
--R;
}
while(L<node[i].l){
--num[a[L]];
tot-=num[a[L]]*2+1;
++L;
}
while(L>node[i].l){
--L;
tot+=num[a[L]]*2+1;
++num[a[L]];
}
ans[node[i].pos].a=tot-(R-L+1);
ans[node[i].pos].b=(ll)(R-L+1)*(R-L);
ans[node[i].pos].reduce();
}
for(int i=1;i<=m;i++)
//printf("%I64d/%I64d\n",ans[i].a,ans[i].b);
printf("%lld/%lld\n",ans[i].a,ans[i].b);
return 0;
}
```
浙公网安备 33010602011771号