无修改的莫队
emmm莫队的几条性质,必须是离线的,复杂度是n*sqrt(n)
就是通过预处理查询区间,然后从(l,r)转移到(ll,rr),这样的复杂度是曼哈顿距离,即abs(l-ll)+abs(r-rr)
通过分块可以保证复杂度在n*sqrt(n)内
详细请参考:https://www.cnblogs.com/Paul-Guderian/p/6933799.html

#include<bits/stdc++.h> #define fi first #define se second #define ll long long #define mp make_pair #define pb push_back #define mod 1000000007 #define pii pair<int,int> #define ls l,m,rt<<1 #define rs m+1,r,rt<<1|1 using namespace std; const int g=10.0,eps=1e-9; const int N=50000+10,maxn=5000000+10,inf=0x3f3f3f3f; struct mo{ int l,r,id; ll a,b; }q[N]; int belong[N],co[N]; ll sum[N],ans; bool cmp(mo a,mo b) { return belong[a.l]==belong[b.l]?a.r<b.r:a.l<b.l; } bool cmp1(mo a,mo b) { return a.id<b.id; } void re(int i,int add) { ans-=sum[co[i]]*sum[co[i]]; sum[co[i]]+=add; ans+=sum[co[i]]*sum[co[i]]; } int main() { /*ios::sync_with_stdio(false); cin.tie(0);*/ int n,m; scanf("%d%d",&n,&m); int block=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&co[i]),belong[i]=i/block+1; for(int i=1;i<=m;i++) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i; sort(q+1,q+1+m,cmp); int l=1,r=0; for(int i=1;i<=m;i++) { while(l<q[i].l)re(l,-1),l++; while(l>q[i].l)re(l-1,1),l--; while(r<q[i].r)re(r+1,1),r++; while(r>q[i].r)re(r,-1),r--; q[i].a=ans-(q[i].r-q[i].l+1); q[i].b=(ll)(q[i].r-q[i].l+1)*(q[i].r-q[i].l); ll x=__gcd(q[i].a,q[i].b); q[i].a/=x;q[i].b/=x; } sort(q+1,q+1+m,cmp1); for(int i=1;i<=m;i++) printf("%lld/%lld ",q[i].a,q[i].b); return 0; } /******************* *******************/