[国家集训队]小Z的袜子-莫队

时间:2020-04-25
本文章向大家介绍[国家集训队]小Z的袜子-莫队,主要包括[国家集训队]小Z的袜子-莫队使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目

题目

程序

莫队。
然后n个同样的袜子选袜子有\(C^2_n\)种不同的选法。
最后辗转相除,开long long(我就因为这个一开始没AC)

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;
typedef long long ll;
const int N=1E5;
ll a[N],n,m;
ll cnt[N],pos[N],siz,res;
ll re[N],all[N];
struct Q {
	ll l,r;
	int id;
}q[N];

ll gcd(ll a,ll b) {
	if(!b)
	  return a;
	return gcd(b,a%b);
}

bool cmp(const Q &a,const Q &b) {
	return pos[a.l]==pos[b.l]?pos[a.r]<pos[b.r]:pos[a.l]<pos[b.l];
}

void add(int p) {
	res-=cnt[a[p]]*(cnt[a[p]]-1)/2;
	cnt[a[p]]++;
	res+=cnt[a[p]]*(cnt[a[p]]-1)/2;
} 

void del(int p) {
	res-=cnt[a[p]]*(cnt[a[p]]-1)/2;
	cnt[a[p]]--;
	res+=cnt[a[p]]*(cnt[a[p]]-1)/2;
}

int main() {
	cin>>n>>m;
	siz=sqrt(n)+1;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
		pos[i]=i/siz;
	}
	for(int i=1;i<=m;i++) {
		cin>>q[i].l>>q[i].r;
		q[i].id=i;
	}
	sort(q+1,q+m+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;i++) {
		while(q[i].l<l)
		  add(--l);
		while(q[i].r>r)
		  add(++r);
		while(q[i].l>l)
		  del(l++);
		while(q[i].r<r)
		  del(r--);
		ll al=(q[i].r-q[i].l+1)*(q[i].r-q[i].l)/2;
		all[q[i].id]=al;
		re[q[i].id]=res;
	}
	for(int i=1;i<=m;i++) {
		ll res=re[i],al=all[i];
		if(res==0) {
			cout<<"0/1"<<endl;
			continue;
		}
		ll lgcd=gcd(al,res);
		cout<<res/lgcd<<'/'<<al/lgcd<<endl;
	}
	return 0;
}

原文地址:https://www.cnblogs.com/wyc06/p/12774568.html