zoukankan      html  css  js  c++  java
  • HYSBZ 2038 小Z的袜子(hose) (莫队算法入门)

    题意:取一段区间,求区间中任取两个数相同的概率;

    思路:所求概率P=(A*(A-1)/2+B*(B-1)/2+......)/(R-L+1)*(R-L)/2化简得P=(A*A+B*B+......+Z*Z-(R-L+1))/(R-L+1)*(R-L);

            将询问区间左端点放在同一分块中处理,每次处理一个块中的所有询问,对于同一块,询问右端点按严格递增处理,左端点不断移动;

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int t,n,m,unit;
    int a[500010],num[500010];
    struct node
    {
        int id,L,R;
    }M[500010];
    int cmp(node a,node b)
    {
        if(a.L/unit!=b.L/unit) return a.L/unit<b.L/unit;
        return a.R<b.R;
    }
    long long gcd(long long a,long long b)
    {
        if(b==0) return a;
        return gcd(b,a%b);
    }
    struct que
    {
        long long a,b;
        void reduce() //分数约分
        {
            long long d=gcd(a,b);
            a/=d;b/=d;
        }
    }ans[500010];
    void work()
    {
        int L=1,R=0;
        long long temp=0;
        memset(num,0,sizeof(num)); //区间中同种数的个数
        for(int i=0;i<m;i++)
        {
            while(R<M[i].R)
            {
                R++;
                temp-=(long long)num[a[R]]*num[a[R]];
                num[a[R]]++;//a[R]的个数加1
                temp+=(long long)num[a[R]]*num[a[R]];
            }
            while(L>M[i].L)
            {
                L--;
                temp-=(long long)num[a[L]]*num[a[L]];
                num[a[L]]++;//a[L]的个数加1
                temp+=(long long)num[a[L]]*num[a[L]];
            }
            while(R>M[i].R)
            {
                temp-=(long long)num[a[R]]*num[a[R]];
                num[a[R]]--;//a[L]的个数减1
                temp+=(long long)num[a[R]]*num[a[R]];
                R--;
            }
            while(L<M[i].L)
            {
                temp-=(long long)num[a[L]]*num[a[L]];
                num[a[L]]--;//a[R]的个数减1
                temp+=(long long)num[a[L]]*num[a[L]];
                L++;
            }
            ans[M[i].id].a=temp-(R-L+1);  
            ans[M[i].id].b=(long long)(R-L)*(R-L+1);
            ans[M[i].id].reduce();
        }
    }
    int main()
    {
        int i,j,k;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            for(i=1;i<=n;i++)
                scanf("%d",&a[i]);
            unit=(int)sqrt(n); //总区间分为unit块
            for(i=0;i<m;i++)
            {
                M[i].id=i;
                scanf("%d%d",&M[i].L,&M[i].R);
            }
            sort(M,M+m,cmp); //对询问排序
            work();
            for(i=0;i<m;i++)
            printf("%lld/%lld
    ",ans[i].a,ans[i].b);
        }
        return 0;
    }
  • 相关阅读:
    Word Ladder
    Word Ladder II
    Valid Palindrome
    java 正则表达式-忽略大小写与多行匹配
    Vue自定义指令
    定义格式化时间的全局过滤器
    Vue过滤器的使用
    daterangepicker 设置默认值为空(转载)
    js时间戳与日期格式之间的互转
    Vuedevtools安装
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4651301.html
Copyright © 2011-2022 走看看