题目大意

给定一个1到n的排列,然后随机选取一个区间,让这个区间内的数随机改变顺序,问这样的一次操作后,该排列的逆序数的期望是多少

首先,一个随机的长度为len的排列的逆序数是(len)*(len-1)/4,这是显然的,因为每种排列倒序一遍就会得到一个新序列,逆序数是len*(len-1)/2 - x(x为原排列的逆序数)

所以我们只需要把所有n*(n-1)/2的区间每种情况都随机化一遍再求逆序对,然后把这个值求和,就可以得到答案了

但是如果用朴素做法,那么复杂度是n^2的

考虑dp[x]表示以x为右端点的所有区间的逆序对数

dp[x] = sigma(dp[1~(x-1)]) + f[x]

f[x]表示x这个数对其以x为右端点所有区间的逆序对数所做的贡献,简单说,就是加了x以后,逆序对增加的个数

那么显然出现在第一位的数的贡献为1,而在第二位的数贡献为2,然后把相应的值加到权值线段树里

就可以统计出来所有的dp[x]了

最终答案就是 原序列的逆序对数-(Sum(dp[x])-Sum(所有区间随机化))/区间个数

PS:精度比较坑,中间整数运算尽量用long long,最后再用long double

#include <iostream>
#include <cstring>
#include <cstdio>
#include <iomanip>
using namespace std;
typedef long double ld;
const int maxn = ;
long long tree[maxn*];
void Insert(int o, int l, int r, int k, int v)
{
if(l == r)
{
tree[o] = v;
return;
}
int mid = (l+r)>>;
if(k <= mid) Insert(o*, l, mid, k, v);
else Insert(o*+, mid+, r, k, v);
tree[o] = tree[o*] + tree[o*+];
} long long Query(int o, int l, int r, int L, int R)
{
if(L <= l && r <= R) return tree[o];
int mid = (l+r)>>;
ld ans = ;
if(L <= mid) ans += Query(o*, l, mid, L, R);
if(R > mid) ans += Query(o*+, mid+, r, L, R);
return ans;
}
int n, x, a[maxn], f[maxn];
int main()
{
cin>>n;
ld ans = ;
for(int i = ; i <= n; i++) cin>>a[i], f[a[i]] = i;
for(int i = ; i <= n; i++)
{
ans += Query(, , n, a[i], n);
Insert(, , n, a[i], );
}
ans *= ((long long)n*(n+));
memset(tree, , sizeof(tree));
long long last = ;
for(int i = ; i <= n; i++)
{
ans -= (last + Query(, , n, a[i], n));
last = last + Query(, , n, a[i], n);
Insert(, , n, a[i], f[a[i]]*);
}
for(int i = ; i <= n; i++)
ans += ((long long)(n-i+)*i*(i-)/);x`
ans /= ((long long)n*(n+));
cout<<setprecision()<<ans<<endl;
}

Codeforces Round #388 (Div. 2) 749E(巧妙的概率dp思想)的更多相关文章

  1. Codeforces Round #164 (Div. 2) E. Playlist 贪心+概率dp

    题目链接: http://codeforces.com/problemset/problem/268/E E. Playlist time limit per test 1 secondmemory ...

  2. Codeforces Round #367 (Div. 2) C. Hard problem(DP)

    Hard problem 题目链接: http://codeforces.com/contest/706/problem/C Description Vasiliy is fond of solvin ...

  3. Codeforces Round #272 (Div. 2) B. Dreamoon and WiFi dp

    B. Dreamoon and WiFi 题目连接: http://www.codeforces.com/contest/476/problem/B Description Dreamoon is s ...

  4. Codeforces Round #388 (Div. 2)

      # Name     A Bachgold Problem standard input/output 1 s, 256 MB    x6036 B Parallelogram is Back s ...

  5. Codeforces Round #388 (Div. 2) - C

    题目链接:http://codeforces.com/contest/749/problem/C 题意:给定一个长度为n的D/R序列,代表每个人的派别,然后进行发表意见,顺序是从1到n.每个人到他的回 ...

  6. Codeforces Round #388 (Div. 2) - B

    题目链接:http://codeforces.com/contest/749/problem/B 题意:给定平行四边形的3个点,输出所有可能的第四个点. 思路:枚举任意两个点形成的直线,然后利用这两个 ...

  7. Codeforces Round #388 (Div. 2) - A

    题目链接:http://codeforces.com/contest/749/problem/A 题意:给定一个数n,求把n分解成尽量多的素数相加.输入素数个数和具体方案. 思路:因为要尽量多的素数, ...

  8. Codeforces Round #388 (Div. 2) A+B+C!

    A. Bachgold Problem 任何一个数都可以由1和2组成,由于n是大于等于2的,也就是可以由2和3组成.要求最多的素数即素数越小越好,很明显2越多越好,如果n为奇数则再输出一个3即可. i ...

  9. Codeforces Round #388 (Div. 2) A,B,C,D

    A. Bachgold Problem time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. 【Java】多线程相关复习—— 线程的创建、名字、运行情况以及顺序控制(join方法) 【一】

    一.创建线程的三种方式 · 继承Thread类 · 实现Runnable接口 · 实现Callable接口 二. 线程状态 · 线程名字 getName() · 线程活动情况 isAlive() · ...

  2. SpringBoot学习11:springboot异常处理方式1(自定义异常页面)

    SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制.一旦程序中出现了异常 SpringBoot 会向/error 的 url 发送请求.在 sprin ...

  3. js一键复制到剪切板

    <div id='demo'>我就是被复制的内容<span>点击复制<span></div> $('#demo').on('click','span', ...

  4. JQuery发起ajax请求,并在页面动态的添加元素

    页面html代码: <li> <div class="coll-tit"><span class="coll-icon">& ...

  5. python 一些基础知识

    Python 注释的原理: 原理:根据对象的引用计数器,对象创建会给对象一个引用计数器属性.如果该属性的值为0,那么该对象会被释放.创建一个字符串对象,但是没有任何引用,计数器为0. Python小整 ...

  6. Windows手工创建服务方法

    需要将程序设置成Windows服务的情况,可以利用一下windows自带的sc命令来创建服务. 该命令的基本用法如下:打开cmd命令, 输入如下信息:1 创建服务:sc create SecServe ...

  7. 最短路径之迪杰斯特拉算法(Java)

    1)Dijkstra算法适用于求图中两节点之间最短路径 2)Dijkstra算法设计比较巧妙的是:在求源节点到终结点自底向上的过程中,源节点到某一节点之间最短路径的确定上(这也是我之前苦于没有解决的地 ...

  8. 理解Queue队列中join()与task_done()的关系

    在网上大多关于join()与task_done()的结束原话是这样的: Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号 ...

  9. 关于 package.json 和 package-lock.json 文件说明

    package.json 在 Node.js 中,模块是一个库或框架,也是一个 Node.js 项目.Node.js 项目遵循模块化的架构,当我们创建了一个 Node.js 项目,意味着创建了一个模块 ...

  10. python几个复习例子

    1.实现1-100的所有的和,程序代码如下: sum = 0 for i in xrange(1,101): sum +=i print (sum) 程序运行结果: 2.实现1-500所有奇数的和,程 ...