洛谷 P1494 [国家集训队] 小 Z 的袜子 题解

区间相同颜色个数,可以离线,我们想到用普通莫队解决。

\(cnt_i\) 表示颜色为 \(i\) 的袜子的数量,则取到两只同颜色的袜子的方案数为 \(\sum^n_{i=1}cnt_i \cdot (cnt_i-1)(cnt_i \ge 2)\),总方案数为 \((r-l+1) \cdot (r-l)\)

注意 long long,笔者因为没开而挂了 3 次/kk

//P1494 [国家集训队] 小 Z 的袜子
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int MAXN=60000;
struct Query
{
	ll l,r,id;
}q[MAXN];
struct Answer
{
	ll x,y;
}ans[MAXN],now;
int n,m,t,num,belong[MAXN],a[MAXN];
ll cnt[MAXN];
ll math_GCD(ll x,ll y)
{
	return !y?x:math_GCD(y,x%y);
}
bool mohs_cmp(Query a,Query b)
{
	return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&1)?a.r<b.r:a.r>b.r);
}
inline void mohs_add(int x)
{
	cnt[x]++;
	if(cnt[x]>1)
	{
		now.x=now.x+cnt[x]*(cnt[x]-1)-(cnt[x]-1)*(cnt[x]-2);
	}
	return;
}
inline void mohs_del(int x)
{
	cnt[x]--;
	if(cnt[x]>0) 
	{
		now.x=now.x+cnt[x]*(cnt[x]-1)-(cnt[x]+1)*cnt[x];
	}
	return;
}
void _div(ll x,ll y,int i)
{
	ll g;
	if(!x)
	{
		x=0;
		y=1;
	}
	else 
	{
		g=math_GCD(x,y);
		x/=g;
		y/=g;
	}
	ans[i].x=x;
	ans[i].y=y;
	return;
}
signed main()
{
	/*freopen("P1494_7.in","r",stdin);
	freopen("P1494_7.out","w",stdout);*/
	ll l,r,ql,qr;
	scanf("%d%d",&n,&m);
	t=sqrt(n);
	num=ceil(n*1.0/t);
	for(int i=1;i<=num;i++)
	{
		for(int j=(i-1)*t+1;j<=i*t;j++)
		{
			belong[j]=i;
		}
	}
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=m;i++)
	{
		scanf("%lld%lld",&q[i].l,&q[i].r);
		q[i].id=i;
	}
	sort(&q[1],&q[m+1],mohs_cmp);
	for(int i=q[1].l;i<=q[1].r;i++)
	{
		mohs_add(a[i]);
	}
	now.y=(q[1].r-q[1].l+1)*(q[1].r-q[1].l);
	_div(now.x,now.y,q[1].id);
	l=q[1].l;
	r=q[1].r;
	for(int i=2;i<=m;i++)
	{
		ql=q[i].l;
		qr=q[i].r;
		while(l<ql)
		{
			mohs_del(a[l++]);
		}
		while(l>ql)
		{
			mohs_add(a[--l]);
		}
		while(r<qr)
		{
			mohs_add(a[++r]);
		}
		while(r>qr)
		{
			mohs_del(a[r--]);
		}
		now.y=(qr-ql+1)*(qr-ql);
		//cout<<q[i].id<<' '<<now.x<<' '<<now.y<<endl;
		_div(now.x,now.y,q[i].id);
	}
	for(int i=1;i<=m;i++)
	{
		printf("%lld/%lld\n",ans[i].x,ans[i].y);
	}
	return 0;
}
/*
 * 洛谷
 * https://www.luogu.com.cn/problem/P1494
 * C++20 -O0
 * 2022.10.1
 */
posted @ 2022-10-01 18:21  Day_Dreamer_D  阅读(228)  评论(0)    收藏  举报