LP_Cong

你的努力程度还没到拼天赋的程度。

HYSBZ 2038 小Z的袜子 莫队算法

保存下莫队模板,原理太容易懂了……慢慢学习!



#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 200005;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
struct query
{
	int l;
	int r;
	int id;

} q[MAXN];
int block[MAXN];
bool cmp(query a, query b)
{
	if (block[a.l] == block[b.l])
		return a.r < b.r;
	return block[a.l] < block[b.l];
}

int a[MAXN];
int res[MAXN];
ll num[MAXN];
ll len[MAXN];
int N, M;

ll add(int a)
{
	ll temp = num[a] * num[a];
	num[a]++;
	return num[a] * num[a] - temp;
}
ll remove(int a)
{
	ll temp = num[a] * num[a];
	num[a]--;
	return num[a] * num[a] - temp;
}

void solve()
{
	int l = 1;
	int r = 1;
	num[a[1]] = 1;
	int ans = 1;

	for (int i = 0; i < M; i++)
	{
		while (q[i].r > r)
			r++, ans += add(a[r]);
		while (q[i].r < r)
			ans += remove(a[r]), r--;
		while (q[i].l > l)
			ans += remove(a[l]), l++;
		while (q[i].l < l)
			l--, ans += add(a[l]);
		res[q[i].id] = ans;
	}
}

int main()
{

	scanf("%d%d", &N, &M);
	int blocksize = sqrt(N);
	for (int i = 1; i <= N; i++)
	{
		scanf("%d", &a[i]);
		num[a[i]] = 0;
		block[i] = (i - 1) / blocksize + 1;
	}
	for (int i = 0; i < M; i++)
	{
		scanf("%d%d", &q[i].l, &q[i].r);
		q[i].id = i;
		len[i] = q[i].r - q[i].l + 1;
	}
	sort(q, q + M, cmp);
	solve();
	for (int i = 0; i < M; i++)
	{
		ll g = gcd(res[i] - len[i], len[i] * (len[i] - 1));
		printf("%lld/%lld\n", (res[i] - len[i]) / g, len[i] * (len[i] - 1) / g);
	}
	return 0;
}

阅读更多
版权声明:Why is everything so heavy? https://blog.csdn.net/lzc504603913/article/details/79960387
上一篇第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B 合约数(启发式合并)
下一篇HYSBZ - 2120 数颜色 (带修改莫队)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭