题目大意:

给定\(n\),\(k\),\(mod\),求随机排列在\(k\)层归并排序下逆序对的期望。

题解

考虑这\(k\)层归并会把序列分成若干个块。

这些块内的顺序是原序列的相对顺序,我们要把这些序列归并起来。

考虑一个块内,每对元素都会有\(\frac{1}{2}\)的概率成为一个逆序对.

所以每个块的贡献就是\(\binom{n}{2}\frac{1}{2}\)。

再考虑块之间的贡献,对于两个元素不在一个块内,考虑这两个元素到它们的块头的序列。如果这两个序列的最大值是这两个元素之一,那么它们肯定不会成为逆序对(思考归并排序的过程),否则它们的位置关系就和它们本身无关了,那么它们成为逆序对的概率还是\(\frac{1}{2}\),最后就是\(\frac{i+j-2}{2*(i+j)}\)

所以我们枚举每种块的长度值算一下就好了。

代码

#include<bits/stdc++.h>
#define N 100009
using namespace std;
typedef long long ll;
int n,k,mod;
ll inv[N],sum[N],ans;
map<int,int>tong;
map<int,int>::iterator it1,it2;
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
inline ll power(ll x,ll y){
ll ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;
y>>=1;
}
return ans;
}
inline void MOD(ll &x){x=x>=mod?x-mod:x;}
inline ll C(ll n){return n*(n-1)/2%mod;}
inline void solve(int l,int r,int k){
if(k==1||l==r){tong[r-l+1]++;return;}
int mid=(l+r)>>1;
solve(l,mid,k-1);solve(mid+1,r,k-1);
}
inline ll calc(int a,int b){
ll ans=1ll*a*b%mod*inv[2]%mod;
for(int i=1;i<=a;++i)MOD(ans=ans-(sum[i+b]-sum[i])+mod);
return ans;
}
int main(){
n=rd();k=rd();mod=rd();
for(int i=1;i<=n;++i)inv[i]=power(i,mod-2),MOD(sum[i]=sum[i-1]+inv[i]);
solve(1,n,k);
for(it1=tong.begin();it1!=tong.end();++it1){
MOD(ans+=C(it1->first)*inv[2]%mod*it1->second%mod);
MOD(ans+=C(it1->second)*calc(it1->first,it1->first)%mod);
}
for(it1=tong.begin();it1!=tong.end();++it1)
for(it2=tong.begin();it2!=tong.end();++it2){
if(it1->first<=it2->first)break;
MOD(ans+=1ll*it1->second*it2->second%mod*calc(it1->first,it2->first)%mod);
}
cout<<ans;
return 0;
}

CF1081G Mergesort Strikes Back的更多相关文章

  1. codeforces1081G Mergesort Strikes Back【期望dp+脑洞】

    首先看这样做的特点,就是分到最后小块里的点合并上去的时候相对顺序不变,所以先加上块内逆序对的期望 合并的时候一定是一边卡住一个大值,另一边跳指针,所以把一个值向右直到有大于它的值位置的一段区间看作一段 ...

  2. ZJOI2019Round#2

    乱听课记录 关于树的分治问题&杂题选讲 张哲宇 边分治 (边分不是很鸡肋吗) 例题一 题目大意:给出两颗有正负边权的树,求出两个点\(u,v​\)使得两棵树中\((u,v)​\)距离的和最大. ...

  3. 一句话CF

    目录 \(\bf {Round \ \#500 \ (Div. \ 1)}\) \(\bf {Round \ \#589 \ (Div. \ 2)}\) \(\bf {Avito \ Cool \ C ...

  4. PTA Iterative Mergesort

    How would you implement mergesort without using recursion? The idea of iterative mergesort is to sta ...

  5. 算法實例-C#-歸併排序-MergeSort

    # 算法实例 # 排序算法Sort 歸併排序MergeSort 算法說明 歸併的思路是任意兩個元素可以比較大小,那麼任意兩個有序的元素集合也可以通過比較大小的方式歸併成一個有序的元素集合 任何的無序元 ...

  6. MergeSort(归并排序)算法Java实现

    归并排序  归并排序 (merge sort) 是一类与插入排序.交换排序.选择排序不同的另一种排序方法.归并的含义是将两个或两个以上的有序表合并成一个新的有序表.归并排序有多路归并排序.两路归并排序 ...

  7. SGU 319. Kalevich Strikes Back (线段树)

    319. Kalevich Strikes Back Time limit per test: 0.5 second(s)Memory limit: 65536 kilobytes input: st ...

  8. ural 1221. Malevich Strikes Back!

    1221. Malevich Strikes Back! Time limit: 1.0 secondMemory limit: 64 MB After the greatest success of ...

  9. mergeSort

    package POJ; public class Main { /** * * MergeSort * */ public static void main(String[] args) { Mai ...

随机推荐

  1. 【Qt开发】Qt Creator在Windows上的调试器安装与配置

    Qt Creator在Windows上的调试器安装与配置 如果安装Qt时使用的是Visual Studio的预编译版,那么很有可能就会缺少调试器(Debugger),而使用MSVC的Qt对应的原生调试 ...

  2. linux下 sleep() 与 usleep()

    usleep() 将进程挂起一段时间, 单位是微秒(百万分之一秒): 头文件: unistd.h 语法: void usleep(int micro_seconds); 返回值: 无 内容说明:本函数 ...

  3. 浅谈CSS的模块化

    一.简介 Web前端模块化:HTML模块化.CSS模块化以及JS模块化三个部分: 二.CSS模块化背景 对于小型项目来说,css的量还不至于庞大,问题没有凸显,而如果要开发和持续维护一个较为大型的项目 ...

  4. java 中的equals()小结

    转载自http://www.cnblogs.com/jackyrong/archive/2006/08/20/481994.html Java中的equals是十分重要的,和= =要区别开来,最近在看 ...

  5. python+selenium模拟鼠标操作

    from selenium.webdriver.common.action_chains import ActionChains #导入鼠标相关的包 ------------------------- ...

  6. python 开启进程两种方法 multiprocessing模块 介绍

    一 multiprocessing模块介绍 python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu\_count\(\)查看),在python中大部分情况需要使用多进 ...

  7. 循环Gray码的生成(非递归)

    #!/usr/bin/env python #coding:utf-8 import sys def gray_code(n): if n < 1: return [] n += 1 array ...

  8. javascript中的继承-寄生组合式继承

    前文说过,组合继承是javascript最常用的继承模式,不过,它也有自己的不足:组合继承无论在什么情况下,都会调用两次父类构造函数,一次是在创建子类原型的时候,另一次是在子类构造函数内部.子类最终会 ...

  9. I - The Values You Can Make (背包求具体方案)

    题目大意 给你n个数,让你用这n个数在组成k的情况下,找到所有的value,这些value也由这n个数组成,且这些value组合在一起能够组成k 解法 看到题目我的想法就是母函数= =不过wa了,后来 ...

  10. linux中的文件类型以及查看文件类型的方法

    Linux文件类型和文件的文件名所代表的意义是两个不同的概念,在linux中文件类型与文件扩展名没有关系.它不像Windows那样是依靠文件后缀名来区分文件类型的,在linux中文件名只是为了方便操作 ...