251小さなZをACWing靴下問題解決羅区P1494 /、

羅区P1494 / ACWing 251の小さなZの問題に対する解決策ソックス

問題の意味

数N(1 <= N <=所与 5E4) 、配列C(1 <= CI <= N)。m個の問い合わせがあり(1 <= M <= 5E4 ) と、Ciの値に対応する区間の数に等しい確率にアクセス可能な二つの異なる位置のいずれかを取るしようとしている各間隔所与[L、R]、最も簡単な整数比出力。注:必須ではありませんオンライン

問題の解決策

このタイトルは、Moのテンプレートのタイトルのチームです。だから、Moのチームは何ですか?Moのチームは、MOイェジンタオの私たちの代表チームは、点字ブロックに基づいて、がんのアルゴリズムです。具体的な方法は次のとおりです。ブロックへの問い合わせ。すべてのお問い合わせは、最初の昇順にLに応じてエンドポイント、および各ブロックにおけるRエンドポイントに応じて、大きい順に、次に小さいです。第一の数のブロックごとに、我々は、暴力との値を取得し、残りは元の範囲の根拠に従って拡張することができます。例を修復するためにチームを持っていない、我々はブロックサイズとして√N、その複雑さはO(n√n)です。この質問は、裸のMoチームボードです。配列を維持することは、直接、各区間の数のCIを開き、ビン順列それをクリック!

コード

#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;
}

おすすめ

転載: www.cnblogs.com/xiaoh105/p/12142133.html