推荐两篇写的比较好的博客:
https://blog.youkuaiyun.com/qq_38891827/article/details/82190013
https://www.cnblogs.com/MashiroSky/p/5914637.html
莫队算法是用来离线解决不修改的区间问题的。
AC代码:694ms
#include<bits/stdc++.h>
#define de cout<<endl<<endl<<endl
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=100010;
using namespace std;
struct node{
int l,r,id;
}b[N];
int a[N],L,R,pos[N],cnt[N];
ll ans1[N],ans2[N],ans;
bool cmp(node b1,node b2)
{
return pos[b1.l]==pos[b2.l]?b1.r<b2.r:pos[b1.l]<pos[b2.l];
}
void add(int x)
{
ans+=cnt[a[x]];
cnt[a[x]]++;
}
void del(int x)
{
cnt[a[x]]--;
ans-=cnt[a[x]];
}
int main()
{
int n,m;scanf("%d%d",&n,&m);
int sz=sqrt(n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),pos[i]=i/sz;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&b[i].l,&b[i].r);
b[i].id=i;
}
sort(b+1,b+m+1,cmp);
L=1;R=0;
for(int i=1;i<=m;i++)
{
while(R<b[i].r) {R++;add(R);}
while(L>b[i].l) {L--;add(L);}
while(L<b[i].l) {del(L);L++;}
while(R>b[i].r) {del(R);R--;}
ans1[b[i].id]=ans;
ans2[b[i].id]=1ll*(b[i].r-b[i].l+1)*(b[i].r-b[i].l)/2;
ll gcd=__gcd(ans1[b[i].id],ans2[b[i].id]);
ans1[b[i].id]/=gcd;
ans2[b[i].id]/=gcd;
if(ans1[b[i].id]==0)
ans2[b[i].id]=1;
}
for(int i=1;i<=m;i++)
printf("%lld/%lld\n",ans1[i],ans2[i]);
return 0;
}
1090

被折叠的 条评论
为什么被折叠?



