【codeforces 749E】 Inversions After Shuffle
http://codeforces.com/problemset/problem/749/E (题目链接)
题意
给出一个1~n的排列,从中等概率的选取一个连续段,设其长度为l。对连续段重新进行等概率的全排列,求排列后整个原序列的逆序对的期望个数。
Solution
考虑对于每一对数${(a_i,a_j),i<j}$算贡献。
1.连续段包含${a_i,a_j}$
不妨设${a_i<a_j}$,则只有当排列后${a_j}$再${a_i}$前面才会对答案有贡献(${a_i>a_j}$的情况同理),连续段长度为${l}$。
于是满足${a_i}$在${a_j}$前面的排列数为${P_l^{l-2}}$,概率:${\frac{P_l^{l-2}}{P_l^l}=\frac{1}{2}}$。
满足包含${a_i}$和${a_j}$的连续段有${i*(n-j+1)}$个,其概率为:${\frac{2*i*(n-j+1)}{n*(n+1)}}$。
所以其期望等于两个概率相乘:
$${q_{i,j}=\frac{i*(n-j+1)}{n*(n+1)}}$$
这是${O(n^2)}$的,考虑优化。总期望:
$${Q=\sum_{i=1}^n \sum_{j=i+1}^n q_{i,j}}$$
$${Q=\sum_{i=1}^n \sum_{j=i+1}^n \frac{i*(n-j+1)}{n*(n+1)}}$$
发现${(n-j+1)}$是连续的,于是就变成了:
$${Q=\sum_{i=1}^n \frac {i*(n-i)*(n-i+1)} {2*n*(n+1)}}$$
这样复杂度就是${O(n)}$的了。
2.连续段不同时包含${a_i,a_j}$
如果${a_i<a_j}$,那么因为不被连续段同时包含,它们不会有机会改变相对位置,所以不会对答案做出贡献。考虑${a_i>a_j}$的情况。
那么连续段可能取到的区间有:${[1,j-1],[i+1,n]}$。考虑到区间${[i+1,j-1]}$被算了2次,容斥一下,所以区间的概率:
$${P_{i,j}=\frac {(j-1)*j+(n-i)*(n-i+1)-(j-i-1)*(j-i)} {n*(n+1)}}$$
$${P_{i,j}=\frac {(n^2+n)-(2*i+2*n*i)+2*i*j} {n*(n+1)}}$$
这个${P_{i,j}}$怎么快速求解呢,考虑逆序对这个东西。
$${Q=\sum_{i=1}^n \sum_{j=i+1}^n \frac {(n^2+n)-(2*i+2*n*i)+2*i*j} {n*(n+1)}}$$
设满足${a_j<a_i,j>i}$的${a_j}$的个数为${x}$,显然${x}$我们可以通过树状数组用求逆序对的方法${O(nlogn)}$的求出来,则:
$${Q=\sum_{i=1}^n \frac {x*((n^2+n)-(2*i+2*n*i)) + \sum_{j=i+1}^n 2*i*j} {n*(n+1)}}$$
那么现在${\sum_{j=i+1}^n 2*i*j}$怎么求呢。把${2*i}$提出去,那么就成了${2*i*\sum_{j=i+1}^n j}$我们用${y}$记录满足${a_j<a_i,j>i}$的${a_j}$的位置的和,也就是${\sum_{j=i+1}^n j}$,那么显然这个东西我们也是可以通过树状数组用求逆序对的方法${O(nlogn)}$的算出来的。则:
$${Q=\sum_{i=1}^n \frac {x*((n^2+n)-(2*i+2*n*i)) + 2*i*y} {n*(n+1)}}$$
于是问题就${O(nlogn)}$的解决了。
细节
mdzz不晓得哪里爆掉了还是精度问题,调了2天,最后莫名AC。。。
代码
// codeforces 749E
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;const int maxn=100010;
LL c[maxn],s[maxn],n;
int a[maxn];
long double ans;int lowbit(int x) {return x&-x;
}
void add(LL *c,int x,LL val) {for (int i=x;i<=n;i+=lowbit(i)) c[i]+=val;
}
LL query(LL *c,int x) {LL res=0;for (int i=x;i;i-=lowbit(i)) res+=c[i];return res;
}void solve1() { //区间包含long double Q=0;for (LL i=1;i<=n;i++)Q+=(long double)(i*(n-i)*(n-i+1))/2/n/(n+1);ans+=Q;
}
void solve2() { //区间不包含long double Q=0;for (int i=n;i>=1;i--) {LL x=query(c,a[i]-1);Q-=(long double)(x*((2*i+2*n*i)-(n*n+n)))/n/(n+1);Q+=(long double)(2*i)/n/(n+1)*query(s,a[i]-1);add(c,a[i],1);add(s,a[i],i);}ans+=Q;
}
int main() {scanf("%lld",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]);solve1();solve2();printf("%.20Lf",ans);return 0;
}
贴一个暴力,供参考:
// codeforces 749E
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf 1<<30
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;const int maxn=100010;
LL c[maxn],s[maxn],n;
int a[maxn];
long double ans;int main() {freopen("aaa.in","r",stdin);freopen("ccc.out","w",stdout);scanf("%lld",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]);for (LL i=1;i<=n;i++)ans+=(long double)(i*(n-i)*(n-i+1))/(2*n*(n+1));long double res=0;for (LL i=n;i>=1;i--) {for (LL j=i+1;j<=n;j++)if (a[i]>a[j]) res+=(long double)((j-1)*j+(n-i)*(n-i+1)-(j-i-1)*(j-i))/(n*(n+1));}ans+=res;printf("%.20Lf",ans);return 0;
}
转载于:https://www.cnblogs.com/MashiroSky/p/6246624.html
【codeforces 749E】 Inversions After Shuffle相关推荐
- 【CodeForces - 144C】Anagram Search(尺取,滑窗问题,处理字符串计数)
题干: A string t is called an anagram of the string s, if it is possible to rearrange letters in t so ...
- 【CodeForces - 574B】Bear and Three Musketeers (枚举边,思维,优秀暴力)
题干: Do you know a story about the three musketeers? Anyway, you will learn about its origins now. Ri ...
- 【CodeForces - 608C】Chain Reaction (二分 或 dp ,思维)
题干: 题目大意: 题意是在一条直线上坐落着不同位置的灯塔,每一个灯塔有自己的power level,当作是射程范围.现在从最右边的灯塔开始激发,如果左边的灯塔在这个灯塔的范围之内,那么将会被毁灭.否 ...
- 「一题多解」【CodeForces 85D】Sum of Medians(线段树 / 分块)
题目链接 [CodeForces 85D]Sum of Medians 题目大意 实现一个setsetset,支持插入,删除,求∑a5k+3∑a5k+3\sum a_{5k+3}.注意,setsets ...
- 【CodeForces 997C】Sky Full of Stars(组合计数)
题目链接:[CodeForces 997C]Sky Full of Stars 官方题解:Codeforces Round #493 - Editorial 题目大意:有一个n×nn×nn\times ...
- 【codeforces 812C】Sagheer and Nubian Market
[题目链接]:http://codeforces.com/contest/812/problem/C [题意] 给你n个物品; 你可以选购k个物品;则 每个物品有一个基础价值; 然后还有一个附加价值; ...
- 【codeforces 508B】Anton and currency you all know
[题目链接]:http://codeforces.com/contest/508/problem/B [题意] 给你一个奇数; 让你交换一次数字; 使得这个数字变成偶数; 要求偶数要最大; [题解] ...
- 【codeforces 711B】Chris and Magic Square
[题目链接]:http://codeforces.com/contest/711/problem/B [题意] 让你在矩阵中一个空白的地方填上一个正数; 使得这个矩阵两个对角线上的和; 每一行的和,每 ...
- 【codeforces 807C】Success Rate
[题目链接]:http://codeforces.com/contest/807/problem/C [题意] 给你4个数字 x y p q 要求让你求最小的非负整数b; 使得 (x+a)/(y+b) ...
最新文章
- SQLite关于时间段查询的sql
- Android调用相机拍摄照片并显示到 ImageView控件中
- js function理解
- neo4j 显示名字_Neo4j:绘制“我的名字是……我在工作”图
- Angular5 *ngIf 和 hidden 的区别
- day20 派生属性和方法,钻石继承
- 翻译 《Why Indy?》计划进度表
- ISO9126软件质量模型
- 友商惭愧不?2000+的手机红米直接干到千元
- nginx ---- 目录结构
- cpu为何有两个温度?
- javacore分析工具_线上死锁定位分析
- php 获取来源域名方法,PHP获取域名方法
- Java开发、网络爬虫、自然语言处理、数据挖掘简介
- mswinsck.ocx 一个文件丢失或无效_AutoCAD文件修复的10种方法
- html5中怎么实现外边框中嵌入字_Web前端有什么优点?Web前端怎么入门?
- linux中文件带方块,JFreeChart图片里的中文在linux下显示为方块的解决办法
- 识别INSB号码C语言如何讲述,探究机器码,深入研究C语言程序的机制
- 基于VHDL的毛刺信号消除
- 两个苹果手机怎么定位_苹果6手机一直闪白屏怎么办?苹果6手机一直闪白屏怎么办?...
热门文章
- Ubuntu网络连接未托管的解决办法
- React开发(255):react项目理解 ant design 注意报错提示
- 前端小知识点(9):函数和对象之间的关系
- 前端学习(3207):js中的事件绑定
- 前端学习(3120):react-hello-react的setstate的使用
- 前端学习(2987):vue+element今日头条管理--案例演示
- [jQuery] Zepto的点透问题如何解决?
- 工作342:消除平时环境的console
- 工作304:uni返回上一页面
- spring mvc学习(27):处理数据模型--从表单到controller传输数据续