bzoj 2038: [2009国家集训队]小Z的袜子(hose) 莫队算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxn 60000
typedef long long ll;
ll gcd(ll x,ll y){
if(x>y)return gcd(y,x);
return x==0?y:gcd(y%x,x);
}
ll S;
struct P{
ll l,r,c;
bool operator<(P a)const{
if((l/S)==(a.l/S))return r<a.r;
else return l<a.l;
}
}aa[maxn];
ll res[maxn];
ll mu[maxn];
ll n,m;
ll a[maxn];
ll cc[maxn];
ll ans;
inline void add(int x){
ans+=2*cc[a[x]];
cc[a[x]]++;
}
inline void dele(int x){
cc[a[x]]--;
ans-=2*cc[a[x]];
}
void solv(ll &x,ll &y){
ll g=gcd(x,y);
x/=g;
y/=g;
}
int main(){
while(scanf("%lld%lld",&n,&m)!=EOF){
ans=0;
memset(cc,0,sizeof(cc));
S=sqrt(n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)scanf("%d%d",&aa[i].l,&aa[i].r),aa[i].c=i;
sort(aa+1,aa+m+1);
for(int i=aa[1].l;i<=aa[1].r;i++)add(i);
res[aa[1].c]=ans;
mu[aa[1].c]=(aa[1].r-aa[1].l+1)*(aa[1].r-aa[1].l);
solv(res[aa[1].c],mu[aa[1].c]);
for(int i=2;i<=m;i++){
if(aa[i].r>aa[i-1].r)for(int j=aa[i-1].r+1;j<=aa[i].r;j++)add(j);
if(aa[i].l<aa[i-1].l)for(int j=aa[i].l;j<aa[i-1].l;j++)add(j);
if(aa[i].l>aa[i-1].l)for(int j=aa[i-1].l;j<aa[i].l;j++)dele(j);
if(aa[i].r<aa[i-1].r)for(int j=aa[i].r+1;j<=aa[i-1].r;j++)dele(j);
res[aa[i].c]=ans;
mu[aa[i].c]=(aa[i].r-aa[i].l+1)*(aa[i].r-aa[i].l);
solv(res[aa[i].c],mu[aa[i].c]);
}
for(int i=1;i<=m;i++){
printf("%lld/%lld\n",res[i],mu[i]);
} }
}