@description@

没头脑和不高兴是一对形影不离的好朋友,他们一起上学也一起玩耍。

这天,这对好朋友聚在一起玩纸牌游戏。他们所玩的纸牌总共有 N 张,每一张上面都有一个 1~N 的数字,任意两张纸牌上的数字都不相同。根据他们制定的游戏规则,在每局游戏的开始,所有的牌需要按照从 1~N 的顺序排好。在开心地玩完了一局牌之后,他们发现牌的顺序被弄得乱七八糟,将它们排好序是一件挺麻烦的事情。

他们将凌乱的纸牌在桌面上排成一排,然后开始了排序工作。不高兴由于在上一局游戏中输了牌,非常不高兴。他只将其中奇数位置的牌排成了升序,然后把剩下的任务推给了没头脑。没头脑非常没头脑,他采取了一个有些笨的排序方式。每次,他找到两张相邻并且顺序不对的牌交换它们,直到整个序列被排好序为止。

乐于探究的你,想要研究在初始排列随机的情况下没头脑花在交换纸牌上的时间。假设没头脑每交换一对纸牌花费的时间为 1,你希望求出他排序时间的期望。此外,为了更好地分析这个问题,你还希望能够计算出所花时间的方差。更进一步地,如果被不高兴排好序的位置发生了变化,你是否还能求出没头脑用来排序时间的期望呢?

题目链接。

@solution@

那个排序次数显然就是逆序对个数。

@part 1:期望@

考虑期望怎么求,可以想到拆解成每一对 (i, j) (i < j) 是逆序对的概率之和。

分几种情况,考虑这样的概率分别是多少:

(1)如果 i, j 都在排序的序列中,则显然贡献 0。

(2)如果 i, j 都不在排序的序列中,应贡献 1/2。

(3)如果 i, j 一个在一个不在,不妨考虑 i 在 j 不在的情况,另一种情况同理可求。

假如 i 是序列中的第 p 个元素,序列总长为 m,枚举 i 的值,得到概率为:

\[\frac{\sum_{k=p}^{n-m+p}{k-1 \choose p-1}{n-k \choose m-p}\times\frac{k-p}{n-m}}{{n\choose m}}
\]

注意到 \(\sum_{k=p}^{n-m+p}{k-1 \choose p-1}{n-k \choose m-p} = {n\choose m}\),于是我们就可以进一步化式子:

\[(\frac{1}{n-m})(\frac{\sum_{k=p}^{n-m+p}{k-1 \choose p-1}{n-k \choose m-p}\times k}{{n\choose m}} - p)
\]

这个 \(\frac{\sum_{k=p}^{n-m+p}{k-1 \choose p-1}{n-k \choose m-p}\times k}{{n\choose m}}\) 其实就是第 p 个元素的期望值。

一开始我使用的是差分 + 一些简单的组合恒等式来推这个期望值,后来发现有一个更巧妙的方法:用连续期望求离散期望。

我们不妨在序列的头部加上 0,给序列的尾部加上 n + 1,这样依然满足序列的性质。

那么相当于从线段 [0, n + 1] 中随机选择 m 个点,划分成 m + 1 个段,第 p 个点的值为前 p 段之和。

那么根据连续期望的常识,这个值 = \(p\times \frac{n+1}{m+1}\)。和另一种方法的答案一样。

综上,求出来的贡献为 \(\frac{p}{n-m}\times(\frac{n+1}{m+1} - 1) = \frac{p}{m+1}\)。

可以统计 (k, i, j) 的个数,满足 k <= i < j 且 i, k 在序列中。最后用个数 / (m + 1) 就是要求的逆序对期望。

用个线段树即可。

@part 2:方差@

至于方差怎么求。。。本来我是想手算的,结果算到一半实在算不下去了,于是查看了一下题解。

结果。。。“大胆猜测方差的表达式是个次数不高的多项式,拉格朗日插值即可。”

【缓缓打出一个问号.jpg】

分类 N 为偶数或奇数,求出来是一个关于 N 的 3 次多项式:

\[\frac{27N^3 - 26N^2 - 87N + 86}{1440} (odd)\\
\frac{27N^3 + 13N^2 + 46N}{1440} (even)\]

@accepted code@

  1. #include <cstdio>
  2. #include <iostream>
  3. using namespace std;
  4. typedef long long ll;
  5. const int MAXN = 100000;
  6. ll gcd(ll x, ll y) {
  7. return y == 0 ? x : gcd(y, x % y);
  8. }
  9. int N, M;
  10. struct segtree{
  11. #define lch (x << 1)
  12. #define rch (x << 1 | 1)
  13. typedef pair<int, int> pii;
  14. struct node{
  15. int le, ri;
  16. int cnt0, cnt1, tag;
  17. ll s, sl, sr, sum;
  18. }t[4*MAXN + 5];
  19. void build(int x, int l, int r) {
  20. t[x].le = l, t[x].ri = r;
  21. t[x].cnt0 = r - l + 1, t[x].tag = -1;
  22. if( l == r ) return ;
  23. int m = (l + r) >> 1;
  24. build(lch, l, m), build(rch, m + 1, r);
  25. }
  26. void maintain(int x, int v) {
  27. if( v == 0 ) {
  28. t[x].cnt0 = t[x].ri - t[x].le + 1, t[x].cnt1 = 0;
  29. t[x].sl = t[x].sr = t[x].sum = 0;
  30. t[x].s = 0, t[x].tag = v;
  31. }
  32. else {
  33. t[x].cnt1 = t[x].ri - t[x].le + 1, t[x].cnt0 = 0;
  34. t[x].sl = t[x].sr = t[x].sum = 0;
  35. t[x].s = 1LL*(t[x].ri - t[x].le + 2)*(t[x].ri - t[x].le + 1)/2, t[x].tag = v;
  36. }
  37. }
  38. void pushdown(int x) {
  39. if( t[x].tag != -1 ) {
  40. maintain(lch, t[x].tag);
  41. maintain(rch, t[x].tag);
  42. t[x].tag = -1;
  43. }
  44. }
  45. void pushup(int x) {
  46. t[x].cnt0 = t[lch].cnt0 + t[rch].cnt0;
  47. t[x].cnt1 = t[lch].cnt1 + t[rch].cnt1;
  48. t[x].s = t[lch].s + t[rch].s + 1LL*t[lch].cnt1*t[rch].cnt1;
  49. t[x].sl = t[lch].sl + t[rch].sl + 1LL*t[lch].cnt1*t[rch].cnt0;
  50. t[x].sr = t[lch].sr + t[rch].sr + 1LL*t[lch].cnt0*t[rch].cnt1;
  51. t[x].sum = t[lch].sum + t[rch].sum;
  52. t[x].sum += 1LL*t[lch].cnt1*t[rch].sl + 1LL*t[lch].s*t[rch].cnt0;
  53. t[x].sum += 1LL*t[rch].cnt1*t[lch].sr + 1LL*t[rch].s*t[lch].cnt0;
  54. }
  55. void change(int x, int ql, int qr, int v) {
  56. if( ql > t[x].ri || qr < t[x].le )
  57. return ;
  58. if( ql <= t[x].le && t[x].ri <= qr ) {
  59. maintain(x, v);
  60. return ;
  61. }
  62. pushdown(x);
  63. change(lch, ql, qr, v);
  64. change(rch, ql, qr, v);
  65. pushup(x);
  66. }
  67. }T;
  68. void print(ll x, ll y) {
  69. ll d = gcd(x, y); x /= d, y /= d;
  70. printf("%lld/%lld\n", x, y);
  71. }
  72. void get1() {
  73. ll K = T.t[1].cnt1, S = T.t[1].sum;
  74. ll x1 = S*4, x2 = (N-K)*(N-K-1)*(K+1), y = 4*(K+1);
  75. print(x1 + x2, y);
  76. }
  77. void get2() {
  78. ll x = N;
  79. if( x & 1 )
  80. print(((27*x - 26)*x - 87)*x + 86, 1440);
  81. else print(((27*x + 13)*x + 46)*x, 1440);
  82. }
  83. int main() {
  84. scanf("%d%d", &N, &M), T.build(1, 1, N);
  85. for(int i=1;i<=N;i+=2) T.change(1, i, i, 1);
  86. get1(), get2();
  87. for(int i=1;i<=M;i++) {
  88. int l, r, v;
  89. scanf("%d%d%d", &l, &r, &v);
  90. T.change(1, l, r, v), get1();
  91. }
  92. }

@details@

注意一下开 long long,其他没了。

@bzoj - 3148@ 没头脑和不高兴的更多相关文章

  1. 【BZOJ】【1927】【SDOI2010】星际竞速

    网络流/费用流 比较简单的一题,对于每个星球,将它拆成两个点,然后二分图建模:左部结点与S相连,流量为1费用为0:右部结点与T相连,流量为1费用为0:对于每条航道x->y,连边x->y+n ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  5. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  6. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. 计算程序运行时间(.net1.1 于.net2.0的区别)在.net2.0中提供了Stopwatch类,简单例子

    1. [代码].NET 2.0      using System.Diagnostics; private Stopwatch stw = new Stopwatch(); private void ...

  2. Spring @Autowired 注释

    @Autowired 注释可以在 setter 方法中被用于自动连接 bean. 你可以在 XML 文件中的 setter 方法中使用 @Autowired 注释来除去 元素. 当 Spring遇到一 ...

  3. vue过渡动画样式

    在进入/离开的过渡中,会有 6 个 class 切换. v-enter:定义进入过渡的开始状态.在元素被插入之前生效,在元素被插入之后的下一帧移除. v-enter-active:定义进入过渡生效时的 ...

  4. 虚拟机配置JAVA_HOME

    1.cp home/fan-vm2/es/tools/jdk-8u111-linux-x64.tar.gz usr/java2.tar -zxvf jdk-8u111-linux-x64.tar.gz ...

  5. C#实现自定义列表

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  6. CSS基础选择器总结

    基础选择器 作用 特点 使用情况 用法 标签选择器 可以选出所有相同的标签,比如p 不能差异化选择 较多 p {color:red;} 类选择器 可以选出1个或多个标签 可以根据需求选择 非常多 .n ...

  7. vue 上拉刷新组件

    背景,项目中经常会出现需要上拉加载更多或者下拉刷新的需求,一直以来呢都是借用各种UI库来实现,但是不知道啥情况,最近在使用的时候,一直有问题,出不了效果,然人很恼火,于是只能自己动手来实现以下, 这次 ...

  8. [工具推荐]001.FlipPDF使用教程

    FlipPDF是一个什么样的软件呢,他有什么实际用途呢?顾名思义,这是一个跟PDF有关的软件,没错它是一款把PDF转换成酷炫书籍的软件,他还支持PDF中的目录,也就是转换成的书籍,目录一样可以跳转的. ...

  9. [Wireshark]_001_入门

    Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直接与网卡进 ...

  10. idea本地Maven仓库不能下载依赖jar包的解决方案

    1.确认maven是否正正常安装,是否配置了环境变量,可以通过命令 mvn -version 看是否显示maven的版本信息. 2.检查maven的setting.xml配置文件中本地仓库位置配置是否 ...