zoukankan      html  css  js  c++  java
  • 【BZOJ】2038: [2009国家集训队]小Z的袜子(hose)

    【题意】给定n个数字ai,每次询问一个区间中随机抽选两个数字,数字相同的概率,以分数最简形式输出。n,ai<=50000。

    【算法】莫队算法

    【题解】参考:莫队……讲稿? by Foreseeable

    使用莫队算法的关键在于维护区间信息的增减。

    对于区间[L,R],令其中数字i的出现次数为xi,则ans=[ ΣC(xi,2) ] / [ C(Σxi,2) ]。

    化简可得,ans=Σx^2-(r-l+1)/C(r-l+1,2)

    维护A数组表示每个数字出现次数,每次区间移动一格:减,变,加。

    异块按左坐标排序,同块按右坐标排序。

    莫队别忘了分块

    优化:

    1.奇偶分块:根据块编号的奇偶性,奇数块内r升序,偶数块内r降序。

    2.块大小:block=n/sqrt(m*2/3)。

    #include<cstdio>
    #include<cctype>
    #include<cmath>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int read(){
        int s=0,t=1;char c;
        while(!isdigit(c=getchar()))if(c=='-')t=-1;
        do{s=s*10+c-'0';}while(isdigit(c=getchar()));
        return s*t;
    }
    const int maxn=50010;
    int n,m,a[maxn],be[maxn],block;
    ll c[maxn],sum,ansA[maxn],ansB[maxn];
    struct cyc{int l,r,id;}b[maxn];
    bool cmp(cyc a,cyc b){return be[a.l]^be[b.l]?a.l<b.l:(be[a.l]&1?a.r<b.r:a.r>b.r);}
    ll gcd(ll a,ll b){return !b?a:gcd(b,a%b);}
    void modify(int x,int p){
        //printf("%d %d
    ",x,p);
        sum-=c[a[x]]*c[a[x]];
        c[a[x]]+=p;
        sum+=c[a[x]]*c[a[x]];
    }    
    int main(){
        n=read();m=read();
        for(int i=1;i<=n;i++)a[i]=read();
        block=(int)(1.0*n/sqrt(1.0*m*2/3));
        for(int i=1;i<=n;i++)be[i]=(i-1)/block+1;
        for(int i=1;i<=m;i++)b[i].l=read(),b[i].r=read(),b[i].id=i;
        sort(b+1,b+m+1,cmp);
        int L=1,R=0;
        sum=0;//
        for(int i=1;i<=m;i++){
            for(int j=L-1;j>=b[i].l;j--)modify(j,1);
            for(int j=R+1;j<=b[i].r;j++)modify(j,1);
            for(int j=L;j<=b[i].l-1;j++)modify(j,-1);
            for(int j=R;j>=b[i].r+1;j--)modify(j,-1);
            ll A=sum-(b[i].r-b[i].l+1),B=1ll*(b[i].r-b[i].l+1)*(b[i].r-b[i].l);
            ll g=gcd(A,B);
            ansA[b[i].id]=A/g;ansB[b[i].id]=B/g;
            L=b[i].l;R=b[i].r;
        }
        for(int i=1;i<=m;i++)printf("%lld/%lld
    ",ansA[i],ansB[i]);
        return 0;
    }
    View Code
  • 相关阅读:
    git commit 合并
    git 管理 Linux 文件系统
    python 全局变量的使用
    JavaScript 中 类型转换
    canconfig 配置命令
    python 调用 shell 命令
    python 3 操作mysql数据库的方法
    python 字符串和整数,浮点型互相转换
    JavaScript 里面的整数 位 操作
    JavaScript 使用 php 的变量
  • 原文地址:https://www.cnblogs.com/onioncyc/p/7253042.html
Copyright © 2011-2022 走看看