zoukankan      html  css  js  c++  java
  • CF1081G Mergesort Strikes Back

    CF1081G Mergesort Strikes Back 

    概率好题

    之前做过一些考察排序本质的题目

    如:[USACO18OPEN]Out of Sorts G 冒泡排序理解之一

    混合快排:[USACO18OPEN]Out of Sorts P 冒泡排序理解之二

    本题考察归并排序。

    考虑所有排列中,两个位置贡献逆序对的概率。

    由于底层是原序列,从底层若干个序列考虑。

    序列内部,序列之间两类逆序对。

    每个序列长度为l,内部方案数l*(l-1)/4(两对1/2概率贡献,归并中相对顺序不变,直接加到答案)

    序列之间?

    归并有一种弹栈、单调的感觉

    可以把序列分成若干块,每块的起点都是前缀最大值。

    且这些块起点放入,整个块顺着就放完了。

    且这些块相对顺序不变,到最后也还是完整的块。

    对于两个序列第i和第j个位置有贡献的概率?

    考虑这i+j个元素,i、j二者之一如果是最大值,那么一定不会有贡献

    否则有1/2概率有贡献。即:(i+j-2)/(i+j)*1/2=1/2-1/(i+j)

    枚举i,处理倒数的前缀和

    序列不同的长度只有2种,做一下就好了。

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define fi first
    #define se second
    #define mk(a,b) make_pair(a,b)
    #define numb (ch^'0')
    #define pb push_back
    #define solid const auto &
    #define enter cout<<endl
    #define pii pair<int,int>
    using namespace std;
    typedef long long ll;
    template<class T>il void rd(T &x){
        char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
    template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
    template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
    template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('
    ');}
    namespace Modulo{
    int mod;
    il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    il int sub(int x,int y){return ad(x,mod-y);}
    il int mul(int x,int y){return (ll)x*y%mod;}
    il void inc(int &x,int y){x=ad(x,y);}
    il void inc2(int &x,int y){x=mul(x,y);}
    il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
    template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
    template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
    }
    using namespace Modulo;
    namespace Miracle{
    const int N=1e5+5;
    int n,k;
    int iv[N],s[N];
    int l1,l2,c1,c2;
    void divi(int l,int r,int d){
        if(d==k||l==r){
            if(!l1) {
                l1=r-l+1;++c1;
            }else if(r-l+1==l1) ++c1;
            else if(!l2) l2=r-l+1,++c2;
            else ++c2;
            return;
        }
        int mid=(l+r)>>1;
        divi(l,mid,d+1);divi(mid+1,r,d+1);
    }
    int calc(int l1,int l2){
        if(!l1||!l2) return 0;
        int ret=mul(l1,l2,qm(2));
        for(reg i=1;i<=l1;++i){
            ret=sub(ret,sub(s[i+l2],s[i]));
        }
        return ret;
    }
    int main(){
        rd(n);rd(k);rd(mod);
        iv[1]=1;
        for(reg i=2;i<=n;++i) {
            iv[i]=mul(mod-mod/i,iv[mod%i]);
        }
        for(reg i=1;i<=n;++i) s[i]=ad(s[i-1],iv[i]);
        divi(1,n,1);
        int ans=ad(mul(c1,l1,(l1-1),qm(4)),mul(c2,l2,(l2-1),qm(4)));
        inc(ans,mul(c1,c1-1,qm(2),calc(l1,l1)));
        inc(ans,mul(c2,c2-1,qm(2),calc(l2,l2)));
        inc(ans,mul(c1,c2,calc(l1,l2)));
        ot(ans);
        return 0;
    }
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
    */
  • 相关阅读:
    ASP.Net Core一个项目中如何支持多种身份认证方式
    c#正则表达式
    Newtonsoft.Json笔记 -JsonPath
    DotLiquid-介绍
    ASP.NET Core-请求频率限制(AspNetCoreRateLimit)
    使用dotnet-gcdump 查找耗内存的大对象【转】
    使用dotnet-dump 查找 .net core占CPU100%的原因【转】
    ADO.NET
    .NET Core-IServiceCollection扩展一个Replace方法
    SafeList-线程安全的List(c#)
  • 原文地址:https://www.cnblogs.com/Miracevin/p/11025479.html
Copyright © 2011-2022 走看看