Socks problem solution Luo Gu P1494 / ACWing 251 small Z,

Luo Gu P1494 / ACWing 251 Socks solution to a problem of small Z

The meaning of problems

Given a number n (1 <= n <= 5e4) sequence C (1 <= ci <= n). There are m inquiry (1 <= m <= 5e4 ), each given an interval [l, r], seeking to take any of two different location accessible to a number equal probability interval corresponding to the value of ci, with The most simple integer ratio output. Note: not mandatory online

answer

This title is a team of Mo template title. So what is it Mo team? Mo team is cancer algorithm based on block our national team of Mo Ye Tao raised. Specific method is: the inquiry into blocks. All inquiries first endpoint according to l in ascending order, and then small to large order in accordance with r endpoints in each block. For each block of the first number, we obtain the value with violence, the rest can be extended according to the basis of the range of the original. Do not bring the team to repair an example, we √n as block size, its complexity is O (n√n) of. This question is bare Mo team board. Maintaining an array directly open a number ci of each interval, and then click on the bin permutations it!

Code

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
    int ret=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return w*ret;
}
int n,m;
int a[50010];
struct node{
    int l,r;
    int id;
}f[50010];
bool cmp1(node p,node q)
{
    if(p.l!=q.l) return p.l<q.l;
    else return p.r<q.r;
}
bool cmp2(node p,node q)
{
    return p.r<q.r;
}
struct node2{
    long long p,q;
}ans[50010];
int t;
int tot;
int lp,rp;
long long cnt=0;
long long tmp[50010];
void cal1(int l,int r)
{
    cnt=0;
    memset(tmp,0,sizeof(tmp));
    for(int i=l;i<=r;i++)
    {
        int x=a[i];
        cnt-=tmp[x]*(tmp[x]-1)/2;
        tmp[x]++;
        cnt+=tmp[x]*(tmp[x]-1)/2;
    }
    lp=l,rp=r;
}
void cal2(int l,int r)
{
    if(lp>l)
    {
        for(int i=l;i<lp;i++)
        {
            int x=a[i];
            cnt-=tmp[x]*(tmp[x]-1)/2;
            tmp[x]++;
            cnt+=tmp[x]*(tmp[x]-1)/2;
        }
        lp=l;
    }
    if(lp<l)
    {
        for(int i=lp;i<l;i++)
        {
            int x=a[i];
            cnt-=tmp[x]*(tmp[x]-1)/2;
            tmp[x]--;
            cnt+=tmp[x]*(tmp[x]-1)/2;
        }
        lp=l;
    }
    if(rp<r)
    {
        for(int i=rp+1;i<=r;i++)
        {
            int x=a[i];
            cnt-=tmp[x]*(tmp[x]-1)/2;
            tmp[x]++;
            cnt+=tmp[x]*(tmp[x]-1)/2;
            rp++;
        }
        rp=r;
    }
}
long long gcd(long long a,long long b)
{
    return (b==0)? a:gcd(b,a%b);
}
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=m;i++) f[i].l=read(),f[i].r=read(),f[i].id=i;
    sort(f+1,f+m+1,cmp1);
    t=sqrt(n);
    tot=n/t;
    if(t*tot<n) tot++;
    for(int i=1;i<=tot;i++)
    {
        int l=(i-1)*t+1,r=min(i*t,n);
        sort(f+l,f+r+1,cmp2);
        start:
        if(f[l].l==f[l].r)
        {
            ans[f[l].id].p=0;
            ans[f[l].id].q=1;
            l++;
            goto start;
        }
        else
        {
            cal1(f[l].l,f[l].r);
            long long num=(long long)(f[l].r-f[l].l+1);
            ans[f[l].id].p=cnt,ans[f[l].id].q=(num-1)*num/2;
        }
        for(int j=l+1;j<=r;j++)
        {
            if(f[j].l==f[j].r)
            {
                ans[f[j].id].p=0;
                ans[f[j].id].q=1;
            }
            else
            {
                cal2(f[j].l,f[j].r);
                long long num=(long long)(f[j].r-f[j].l+1);
                ans[f[j].id].p=cnt,ans[f[j].id].q=(num-1)*num/2;
            }
        }
    }
    for(int i=1;i<=m;i++)
    {
        long long x=gcd(ans[i].p,ans[i].q);
        printf("%lld/%lld\n",ans[i].p/x,ans[i].q/x); 
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/xiaoh105/p/12142133.html