• 小Z的袜子 莫队入门


    https://www.lydsy.com/JudgeOnline/problem.php?id=2038

     思路:离线做法,将所有的询问先存下来,然后将区间分为sqrt(n)份,然后按照区间给询问排个序,按照询问区间左端点所在的块为第一排序顺序,询问区间右端点为第二排序标准。

    之后就是通过利用两个指针在询问区间来回移动,前提是每改变一个位置可以O(1)的得到它增加或减少这个元素所对应的值,每变化一个元素就要改变它所对应的答案值。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int maxn=1e5+10;
    int color[maxn];
    struct note
    {
        ll id,l,r,fz,fm;
    } ans[maxn];
    int block[maxn];
    int sum[maxn];
    int cmp1(note a,note b)
    {
        if(block[a.l]<block[b.l]) return 1;
        if(block[a.l]>block[b.l]) return 0;
        return a.r<b.r;
    }
    ll cmp2(note a,note b)
    {
        return a.id<b.id;
    }
    int gcd(ll a,ll b)
    {
        return a%b==0?b:gcd(b,a%b);
    }
    
    int main()
    {
        int n,q;
        scanf("%d%d",&n,&q);
        for(int i=1; i<=n; i++)
            scanf("%d",&color[i]);
        for(int i=1; i<=q; i++)
        {
            scanf("%d%d",&ans[i].l,&ans[i].r);
            ans[i].id=i;
        }
        block[0]=sqrt(n);
        for(int i=1; i<=n; i++)
            block[i]=(i-1)*block[0]+1;
        sort(ans+1,ans+q+1,cmp1);
        int last_l,last_r;
        last_l=1;
        last_r=0;
        ll temp=0;
        for(int i=1; i<=q; i++)
        {
            ans[i].fm=(ans[i].r-ans[i].l+1)*(ans[i].r-ans[i].l);
            if(last_l<ans[i].l)
            {
                for(int j=last_l; j<ans[i].l; j++)
                {
                    temp=temp-(sum[color[j]]*2-1);
                    sum[color[j]]--;
                }
            }
            if(last_l>ans[i].l)
            {
                for(int j=last_l-1; j>=ans[i].l; j--)
                {
                    temp=temp+(sum[color[j]]*2+1);
                    sum[color[j]]++;
                }
            }
            if(last_r<ans[i].r)
            {
                for(int j=last_r+1; j<=ans[i].r; j++)
                {
                    temp=temp+(sum[color[j]]*2+1);
                    sum[color[j]]++;
                }
            }
            if(last_r>ans[i].r)
            {
                for(int j=last_r; j>ans[i].r; j--)
                {
                    temp=temp-(sum[color[j]]*2-1);
                    sum[color[j]]--;
                }
            }
            ans[i].fz=temp-(ans[i].r-ans[i].l+1);
            last_l=ans[i].l;
            last_r=ans[i].r;
        }
        sort(ans+1,ans+1+q,cmp2);
        for(int i=1; i<=q; i++)
        {
    //        printf("%lld %lld
    ",ans[i].fz,ans[i].fm);
            if(ans[i].fz==0)
            {
                printf("0/1
    ");continue;
            }
            ll t=gcd(ans[i].fz,ans[i].fm);
            printf("%lld/%lld
    ",ans[i].fz/t,ans[i].fm/t);
        }
    }
  • 相关阅读:
    线程池问题
    高级I/O
    闹钟设计
    线程竞争问题
    线程基本函数
    SpringMvc支持跨域访问
    gitlab qq邮件配置
    gitlab断电
    docker run always
    电子书网
  • 原文地址:https://www.cnblogs.com/dongdong25800/p/11375610.html
Copyright © 2020-2023  润新知