莫队
orz 莫涛大爷真的是强
明明是暴力的说改变顺(xun)序差别咋就这么大捏?
对于一个询问,我们设
num[x]
是当前区间内颜色为
x
的袜子个数,答案是
then, 对于当前状态,若分子是已知的,那么左边界或右边界改变 1 的状态,可以
最标准的做法是搞出询问位置的曼哈顿距离最小生成树然后再做的。。
だから,我们有某种十分
分成 n√ 块,左界在同一块里按照右界排序,否则按左界排序。
那末复杂度大约是 O(n1.5)
记!得!开! long ! long !
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define g getchar()
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
inline ll read(){
ll x=0,f=1;char ch=g;
for(;ch<'0'||ch>'9';ch=g)if(ch=='-')f=-1;
for(;ch>='0'&&ch<='9';ch=g)x=x*10+ch-'0';
return x*f;
}
inline void out(ll x){
int a[25],wei=0;
if(x<0)putchar('-'),x=-x;
for(;x;x/=10)a[++wei]=x%10;
if(wei==0){puts("0");return;}
for(int j=wei;j>=1;--j)putchar('0'+a[j]);
putchar('\n');
}
ll fz,fm;
struct re{int l,r,id;}ask[50005];
struct re2{ll up,down;}ans[50005];
int c[50005],a[50005],n,Q,block;
ll gcd(ll x,ll y){return y==0?x:gcd(y,x%y);}
inline bool cmp(re x,re y){return x.l/block==y.l/block?x.r<y.r:x.l<y.l;}
inline int update(int p,int x){
fz-=(ll)c[a[p]]*(c[a[p]]-1ll);
c[a[p]]+=x;
fz+=(ll)c[a[p]]*(c[a[p]]-1ll);
}
int main(){
// freopen("","r",stdin);
// freopen("","w",stdout);
n=read(),Q=read();
for(int i=1;i<=n;++i)a[i]=read();
for(int i=1;i<=Q;++i)ask[i].l=read(),ask[i].r=read(),ask[i].id=i;
block=(int)sqrt(n+0.0);
sort(ask+1,ask+1+Q,cmp);
fz=a[1]==a[2]?2:0;
fm=2;
c[a[1]]++;c[a[2]]++;
for(int i=1,l=1,r=2;i<=Q;++i){
for(;r>ask[i].r;)update(r,-1),--r;
for(;l<ask[i].l;)update(l,-1),++l;
for(;l>ask[i].l;)--l,update(l,1);
for(;r<ask[i].r;)++r,update(r,1);
fm=(ll)(r-l+1ll)*(r-l);
ll gx=gcd(fz,fm);
ans[ask[i].id]=(re2){fz/gx,fm/gx};
}
for(int i=1;i<=Q;++i)printf("%lld/%lld\n",ans[i].up,ans[i].down);
return 0;
}