题目:
bzoj 2038
分析:莫队算法模版题。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define LL long long
const int maxn=50003;
using namespace std;
struct node{
int l,r,id;
LL x,y;
}q[maxn];
int n,m,l,r,block,sum,i;
int a[maxn],belong[maxn],t[maxn],ans=0;
bool cmp(node a,node b)
{
if (belong[a.l]==belong[b.l]) return a.r<b.r;
return belong[a.l]<belong[b.l];
}
bool cmp1(node a,node b)
{
return a.id<b.id;
}
void updata(int x,int y)
{
if (y==1)
{
ans+=t[a[x]];
t[a[x]]++;
}
else
{
ans-=t[a[x]]-1;
t[a[x]]--;
}
}
LL gcd(LL x,LL y)
{
LL r=x%y;
while (r!=0)
{
x=y;
y=r;
r=x%y;
}
return y;
}
int main()
{
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for (i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
block=trunc(sqrt(n));
sum=n/block+(n%block!=0);
for (i=1;i<=n;i++)
{
belong[i]=(i-1)/block+1;
}
sort(q+1,q+1+m,cmp);
l=1;r=1;
updata(1,1);
for (i=1;i<=m;i++)
{
for (r;r<q[i].r;r++)
updata(r+1,1);
for (r;r>q[i].r;r--)
updata(r,0);
for (l;l<q[i].l;l++)
updata(l,-1);
for (l;l>q[i].l;l--)
updata(l-1,1);
if (ans==0)
{
q[i].x=0;
q[i].y=1;
continue;
}
q[i].x=ans;
q[i].y=(long long)(q[i].r-q[i].l+1)*(q[i].r-q[i].l)/2;
LL k=gcd(q[i].x,q[i].y);
q[i].x/=k; q[i].y/=k;
}
sort(q+1,q+1+m,cmp1);
for (i=1;i<=m;i++)
{
printf("%lld/",q[i].x);
printf("%lld\n",q[i].y);
}
}