P1494 [国家集训队]小Z的袜子 基础莫队
P1494 [国家集训队]小Z的袜子
标签
- 基础莫队
前言
- 我的csdn和博客园是同步的,欢迎来访danzh-博客园~
简明题意
- 查询区间[L,R]选出两个相等的数的概率
思路
- 莫队很好打,这题难点在于指针移动后概率如何更新。
- 令cnt[]为当前区间每个数出现的次数,l,r表示当前区间的端点,于是这个区间的答案就应该是:
\[\frac{\sum\limits_{x(cnt[x>=2])} C_{cnt[x]}^{2}}{C_{r-l+1}^{2}}
\]
- (下面省略cnt[x]>=2)把组合数拆开:
\[\frac{\sum\limits_{x}( cnt[x](cnt[x]-1)}{(r-l+1)(r-l)}
\]
- 发现分子比较好处理,先减掉cnt[x]原先的贡献,再加上新的贡献就可以了,现在问题在于分母的处理。
\[(r-l+1)(r-l)
\]
- 其实也很好处理鸭。把r-l看成一个整体,然后就很简单了。然后我们应该多开一个变量维护r-l的值,就可以了
注意事项
- longlong
总结
- 初始时l=1,r=0,那么初始时的r-l应该是-1
AC代码
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 5e4 + 10;
long long gcd(long long a, long long b)
{
	if (b == 0) return a;
	return gcd(b, a % b);
}
struct Query
{
	int l, r, id, k;
	bool operator <(const Query& a)const
	{
		if (k == a.k)
			return r < a.r;
		return k < a.k;
	}
};
Query query[maxn];
int n, q, a[maxn];
long long cnt[maxn];
long long mu = 0, zi = 0, r_l = -1;
void add(int x)
{
	x = a[x];
	mu += 2 * r_l + 2, r_l++;
	zi -= cnt[x] * cnt[x] - cnt[x];
	cnt[x]++;
	zi += cnt[x] * cnt[x] - cnt[x];
}
void remove(int x)
{
	x = a[x];
	mu -= 2 * r_l, r_l--;
	zi -= cnt[x] * cnt[x] - cnt[x];
	cnt[x]--;
	zi += cnt[x] * cnt[x] - cnt[x];
}
pair<long long, long long> ans0[maxn];
void solve()
{
	scanf("%d%d", &n, &q);
	int len = sqrt(n / 2 * 3);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	for (int i = 1; i <= q; i++)
		scanf("%d%d", &query[i].l, &query[i].r), query[i].id = i, query[i].k = (query[i].l - 1) / len + 1;
	sort(query + 1, query + 1 + q);
	int l = 1, r = 0;
	for (int i = 1; i <= q; i++)
	{
		int L = query[i].l, R = query[i].r, id = query[i].id;
		while (l < L) remove(l++);
		while (l > L) add(--l);
		while (r < R) add(++r);
		while (r > R) remove(r--);
		if (zi == 0 || L == R) ans0[id].first = 0, ans0[id].second = 1;
		else
		{
			long long t = gcd(zi, mu);
			ans0[id].first = zi / t, ans0[id].second = mu / t;
		}
	}
	for (int i = 1; i <= q; i++)
		printf("%lld/%lld\n", ans0[i].first, ans0[i].second);
}
int main()
{
	freopen("Testin.txt", "r", stdin);
	solve();
	return 0;
}
作者:danzh
QQ:1244536605
CSDN(和博客园同步):https://blog.csdn.net/weixin_42431507
-----------------------------------------------------------------------------------------------
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其
它人怎么样,我们也能够保持自己的本色走下去。
—clj

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号