[Explanations] small Z socks

Final exam is over, blog to write about it

Title Description

As an undisciplined life of people, the small Z every morning takes a long time to find one pair from a pile of colorful socks to wear. Finally one day, the small Z can no longer tolerate this annoying process to find socks, so he decided resigned ......

Specifically, this small Z N socks numbered from 1 to N, and from the number L to R (L despite the small Z does not care two pair of socks is not complete, even two socks do not care whether a left Right, he is very concerned about the color of socks, after all, wearing two different colored socks will be very embarrassing.

Your task is to tell the small Z, how old he is able to get the same probability of two color socks. Of course, the small Z hope that this probability as high as possible, so he could ask more (L, R) in order to facilitate their choice.

However, there is data in the case of L = R, Laid judgment this case, the output 0/1.

Input and output formats

Input formats:

 

The first line of the input file contains two positive integers N and M. N is the number of socks, M to ask a small number of Z mentioned. The next line contains N positive integers Ci, where Ci denotes the i socks color, the same color represented by the same numbers. The next M rows, each row two positive integers L, R represents a query.

 

Output formats:

 

Comprises M rows, each interrogation output score for row A in / B represents the same two randomly color probability socks from the interrogation interval [L, R] in. If the probability is 0 0/1 output, otherwise the output of the A / B must be the most simple fraction. (See 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

solution:

First to push the wave equation

 

For [l, r] the interval of view, the number of programs selected for the socks:

(r-l+1)*(r-l)

Topics requirements demand probability interval selected the same socks, that is

Provided CNT [i] is the number of colors (the [l, r] interval) appeared sock i

sigma(i=0~n)cnt[i]*cnt[i-1]*[cnt[i]>=2)]

Write a gcd (handwritten faster), and divided by the gcd can be. Japanese sentence l == r and where no solution.

Mo team, offline ordering, maintenance intervals and square.

Note that the calculated length of the interval to be subtracted and squared.

Put another method may also push the formulas:

Has a ... x color socks, then there is:

(a*(a-1)/2+b*(b-1)/2+...)/[(r-l+1)*(r-l)]

Inside simplification was

(a2+b2+...-(a+b+...))/[(r-l+10*(r-l)]

即(a2+b2+...-(r-l+1))/[(r-l+1)*(r-l)]

Code:

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXN=500005;
inline void read(int &x){
    ll s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')w=-1;
        ch=getchar();
    }while(ch>=48&&ch<='9'){
        s=(s<<1)+(s<<3)+(ch^48);
        ch=getchar();
    }x=s*w;
}
ll ans,cnt[MAXN];
int n,m,a[MAXN],block;
struct node{
    int l,r,id;
    ll a,b;
}q[MAXN];
inline bool cmp(node a,node b){
    return (a.l/block)^(b.l/block)?a.l<b.l:(((a.l/block)&1)?a.r<b.r:a.r>b.r);
}
inline void update(ll x,ll add){
    ans-=cnt[a[x]]*cnt[a[x]];
    cnt[a[x]]+=add;
    ans+=cnt[a[x]]*cnt[a[x]];
}
inline bool cmpi(node a,node b){
    return a.id<b.id;
}
inline ll gcd(ll a,ll b){
    return !b?a:gcd(b,a%b);
}
int main(){
    read(n);read(m);
    for(int i=1;i<=n;++i)read(a[i]);
    block=sqrt(n);
    for(int i=1;i<=m;++i){
        read(q[i].l);
        read(q[i].r);
        q[i].id=i;
    }sort(q+1,q+m+1,cmp);
    for(int i=1,l=1,r=0;i<=m;++i){
        int ql=q[i].l,qr=q[i].r;
        while(l<ql)update(l,-1),l++;
        while(l>ql)update(--l,1);
        while(r<qr)update(++r,1);
        while(r>qr)update(r,-1),r--;
        if(ql==qr){
            q[i].a=0;
            q[i].b=1;
            continue;
        }
        q[i].a=ans-(qr-ql+1);
        q[i].b=(qr-ql+1)*1LL*(qr-ql);
        long long g=gcd(q[i].a,q[i].b);
        q[i].a/=g;q[i].b/=g;
    }sort(q+1,q+m+1,cmpi);
    for(int i=1;i<=m;++i)printf("%lld/%lld\n",q[i].a,q[i].b);
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/h-lka/p/11128566.html