Inversions After Shuffle CodeForces - 749E (概率,期望)
阿新 • • 發佈:2019-05-03
putchar ack 維數 cond pre using math algo tdi
大意: 給定一個$n$排列, 隨機選一個區間, 求將區間隨機重排後整個序列的逆序對期望.
考慮對區間$[l,r]$重排後逆序對的變化, 顯然只有區間[l,r]內部會發生改變
而長為$k$的隨機排列期望逆序為$\frac{k(k-1)}{4}$(證明考慮逆序與順序對稱性)
所以$[l,r]$的貢獻即為$inv(1,n)-inv(l,r)+\frac{(r-l+1)(r-l)}{4}$
所以就轉化為求$\sum\limits_{1\le l\le r\le n}inv(l,r)$
對於逆序對$(x,y)$, 我們枚舉$y$, 就有貢獻$(n-y+1)\sum\limits_{\substack{1\le x< y\\ a_y<a_x}}x$
就轉化為二維數點問題, 可以用樹狀數組解決.
用$long\space double$不知道為什麽會WA, 改成$double$直接過了
#include <iostream> #include <sstream> #include <algorithm> #include <cstdio> #include <math.h> #include <set> #include <map> #include <queue> #include <string> #include <string.h> #include <bitset> #define REP(i,a,n) for(int i=a;i<=n;++i) #define PER(i,a,n) for(int i=n;i>=a;--i) #define hr putchar(10) #define pb push_back #define lc (o<<1) #define rc (lc|1) #define mid ((l+r)>>1) #define ls lc,l,mid #define rs rc,mid+1,r #define x first #define y second #define io std::ios::sync_with_stdio(false) #define endl ‘\n‘ #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<‘ ‘;hr;}) using namespace std; typedef long long ll; typedef double db; const int N = 1e5+10; int n; db c[2][N]; void add(int id, int x, int v) { for (; x; x^=x&-x) c[id][x]+=v; } db qry(int id, int x) { db ret = 0; for (; x<=n; x+=x&-x) ret+=c[id][x]; return ret; } int main() { scanf("%d", &n); db ans = 0; REP(i,1,n) { int t; scanf("%d", &t); ans += qry(0,t)*n*(n+1)/2-(n-i+1)*qry(1,t)+((db)i*i*i-i)/12; add(0,t,1), add(1,t,i); } ans /= (db)n*(n+1)/2; printf("%.12lf\n", ans); }
Inversions After Shuffle CodeForces - 749E (概率,期望)