[BZOJ2038]: [2009 National Team] small Z socks (hose) (offline Mo Team)

Topic Portal


Title Description

As an undisciplined life of people, small $ Z $ has to spend a day in the morning for a long time to wear one pair to find out from a pile of colorful socks. Finally one day, the small Z can no longer tolerate this annoying process to find socks, so he decided resigned ......
Specifically, this little $ Z $ $ $ N $ sock from $ 1 to $ N $ numbers, and from numbers $ L $ to $ R $ ($ L $ Although small and do not care two $ Z $ is not a complete pair of socks, two socks do not care even if either side, he is very concerned about the color of socks, after all, wear two different color socks will be very embarrassing).
Your task is to tell small $ Z $, how much he's able to get the same probability of two color socks. Of course, small $ Z $ hope that this probability as high as possible, so that he may ask more than $ (L, R) $ in order to facilitate their choice.


Input Format

The first line of the input file contains two positive integers $ N $ and $ M $.
$ N $ is the number of socks, $ M $ is the number of small $ Z $ mentioned in the inquiry.
The next line contains $ N $ $ C_i $ positive integers, wherein C_i $ $ $ I $ denotes socks color, the same color represented by the same numbers.
The next $ M $ lines, each two positive integers $ L $, $ R $ represents a query.


Output Format

$ M $ line comprising, for each query output score $ A / B $ $ represented from the inquiry interval [L, R] $ randomly selected two socks same color probability in a row.

If the probability is $ 0 $ 0 $ output / $ 1, otherwise the output of the $ A / B $ must be the most simple fraction. (See sample)


Sample

Sample input

6 4
1 2 3 3 3 2
2 6
1 3
3 5
1 6

Sample Output

2/5
0/1
1/1
4/15


Data range and tips

Sample explained:

Inquiry 1: Total $ C_5 ^ 2 = 10 $ possible, wherein extracting two $ 2 $ with a $ 1 $ possible to extract two $ 3 $ has $ 3 $ possible, the probability of $ \ frac {1 + 3} {10} = \ frac {4} {10 } = 2/5 $.
Inquiry 2: Total $ C_3 ^ 2 = 3 $ possible, not able to get the same color socks probability $ \ frac {0} {3 } = 0/1 $.
Inquiry 3: Total $ C_3 ^ 2 = 3 $ possible, two are drawn $ 3 $, probability $ \ frac {3} {3 } = 1/1 $.
Note: The above $ C_a ^ b $ denotes the number of combinations, the number of combinations $ C_a ^ b $ $ b is equivalent to the selection of a selection scheme of $ $ $ A different articles.

Data scale and conventions:

30% of the data, $ N, M \ leqslant 5,000 $;
60% of the data, $ N, M \ leqslant 25,000 $;
100% of the data, $ N, M \ leqslant 50,000 $, $ 1 \ leqslant L < R \ leqslant N $, $ C_i \ leqslant N $.


answer

Provided $ k $ interval have different colors, each color $ s [i] $ a, the answer is: $ \ sum \ limits_ {i = 1} {k} \ frac {C_ {s_i} ^ 2} {C_n ^ 2} $.

After the discovery of long maintenance $ s_i ^ 2 $ to open a barrel at the end will be able to move around easily maintain it.

Of what the above formula, you will find out that the answer is: $ \ sum \ limits_ {i = 1} {k} \ frac {(s_i-1) \ times s_i} {(n-1) \ times n} $ , so that the code is much easier to achieve.


Code time

#include<bits/stdc++.h>
using namespace std;
struct rec
{
	int l;
	int r;
	int id;
	int pos;
}q[50001];
int n,m;
int a[50001];
int cnt[50001];
long long ans;
long long a1[50001],a2[50001];
bool cmp(rec a,rec b){return a.pos==b.pos?a.r<b.r:a.pos<b.pos;}
void upd(int x,int w)//计算答案
{
	ans-=cnt[a[x]]*cnt[a[x]];
	cnt[a[x]]+=w;
	ans+=cnt[a[x]]*cnt[a[x]];
}
int main()
{
	scanf("%d%d",&n,&m);
	int t=sqrt(n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&q[i].l,&q[i].r);
		q[i].id=i;
		q[i].pos=(q[i].l-1)/t+1;
	}
	sort(q+1,q+m+1,cmp);
	int l=1,r=0;
	for(int i=1;i<=m;++i)
	{
		while(l<q[i].l)upd(l++,-1);
		while(l>q[i].l)upd(--l,1);
		while(r<q[i].r)upd(++r,1);
		while(r>q[i].r)upd(r--,-1);
		if(l==r){a1[i]=0,a2[i]=1;}
		long long x=ans-(r-l+1);//分子
		long long y=(long long)(q[i].r-q[i].l+1)*(q[i].r-q[i].l);//分母
		long long g=__gcd(x,y);//约分
		a1[q[i].id]=x/g,a2[q[i].id]=y/g;
	}
	for(int i=1;i<=m;i++)
		cout<<a1[i]<<'/'<<a2[i]<<endl;
	return 0;
}

rp ++

Guess you like

Origin www.cnblogs.com/wzc521/p/11240851.html