题目链接

题意:

对于长度为$n$的排列,在已知一些位的前提下求逆序对的期望

思路:

将答案分为$3$部分

$1.$$-1$与$-1$之间对答案的贡献。由于逆序对考虑的是数字之间的大小关系,故假设$-1$的数量为$cnt$,可以等效成求长度为$cnt$的排列的逆序对期望。设$dp[i]$为长度为$i$的全排列的逆序对期望,有$dp[i]=dp[i-1]+$$\frac{i-1}{2}$,可以理解成在原$dp[i-1]$的基础上,数值$i$对每个长度为$i-1$的排列产生$\sum_{t=1}^{i-1}t$个逆序对,共有$(i-1)!$个排列,所以期望为$\frac{(i-1)!*i*(i-1)}{(2*i!)}$$=\frac{i-1}{2}$,移项后使用累加法可以求出通项为$dp[i]=$$\frac{i*(i-1)}{4}$。

$2.$非$-1$之间对答案的贡献。可以将出现概率看作$1$,所以贡献就是逆序对数量,用树状数组求。

$3.$$-1$与非$-1$之间的贡献。设共有$cnt$个$-1$,考虑每个$a[i]$$\neq$$-1$,设这个$a[i]$它前边$-1$的数量为$nop$,它大的未填的数的数量为$high[a[i]]$,那么$a[i]$对这部分答案的贡献为$\frac{nop*high[a[i]]*(cnt-1)!}{cnt!}$$=$$\frac{nop*high[a[i]]}{cnt}$。比$a[i]$小的数与$a[i]$后边的$-1$构成类似的关系。

代码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <cassert>
#include <cstring>
#include <iostream>
#include <algorithm> #define IOS ios::sync_with_stdio(0),cin.tie(0);
#define DBG(x) cerr << #x << " = " << x << endl; #define PII pair<int,int>
#define FI first
#define SE second using namespace std; typedef long long LL;
typedef long double LD;
typedef unsigned long long ULL; const int inf = 0x3f3f3f3f;
const int mod = 998244353;
const double eps = 1e-8;
const double pi = acos(-1.0); void file(){
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
} namespace BakuretsuMahou{ const int N = 2e5 + 5;
const int inv2 = (mod + 1) / 2; int n, a[N], vis[N];
int high[N], low[N];
int pre[N], cnt;
LL ans, fac[N]; LL add(LL a, LL b){
return (a+b)%mod;
} LL mul(LL a, LL b){
return (a*b)%mod;
} struct BIT{ int c[N]; int lowbit(int x){
return (x)&(-x);
} void update(int x, int y){
while(x <= n){
c[x] += y;
x += lowbit(x);
}
} LL query(int x){
LL res = 0;
while(x >= 1){
res += c[x];
x -= lowbit(x);
}
return res;
}
}tree; LL qpow(LL a, LL b, LL p){
LL res = 1;
while(b){
if(b&1)res = mul(res, a);
a = mul(a, a);
b >>= 1;
}
return res;
} LL Fermat(LL a, LL p){
return qpow(a, p - 2, p);
} LL dp(LL x){
return mul(mul(x, x - 1), Fermat(4, mod));
} void init(){
fac[0] = 1;
for(int i = 1; i < N; i++){
fac[i] = mul(fac[i - 1], i);
}
} void Explosion(){
init();
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
if(a[i] != -1){
vis[a[i]] = 1;
ans = add(ans, i - 1 - cnt - tree.query(a[i]));
tree.update(a[i], 1);
}else cnt++, pre[i]++;
pre[i] += pre[i - 1];
}
ans = add(ans, dp(cnt));
LL inv = Fermat(cnt, mod);
for(int i = 2; i <= n; i++)low[i] = low[i - 1] + (vis[i - 1] ^ 1);
for(int i = n - 1; i >= 1; i--)high[i] = high[i + 1] + (vis[i + 1] ^ 1);
for(int i = 1; i <= n; i++){
if(a[i] != -1){
LL nop = pre[i], nos = pre[n] - pre[i];
ans = add(ans, mul(mul(nos, low[a[i]]), inv));
ans = add(ans, mul(mul(nop, high[a[i]]), inv));
}
}
printf("%I64d\n", ans);
}
} int main(){
//IOS
//file();
BakuretsuMahou::Explosion();
return 0;
}

Codeforces 1096F(dp + 树状数组)的更多相关文章

  1. Codeforces 1111E DP + 树状数组 + LCA + dfs序

    题意:给你一颗树,有q次询问,每次询问给你若干个点,这些点可以最多分出m组,每组要满足两个条件:1:每组至少一个点,2:组内的点不能是组内其它点的祖先,问这样的分组能有多少个? 思路:https:// ...

  2. 树形DP+树状数组 HDU 5877 Weak Pair

    //树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...

  3. bzoj 1264 [AHOI2006]基因匹配Match(DP+树状数组)

    1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 793  Solved: 503[Submit][S ...

  4. 【bzoj2274】[Usaco2011 Feb]Generic Cow Protests dp+树状数组

    题目描述 Farmer John's N (1 <= N <= 100,000) cows are lined up in a row andnumbered 1..N. The cows ...

  5. 奶牛抗议 DP 树状数组

    奶牛抗议 DP 树状数组 USACO的题太猛了 容易想到\(DP\),设\(f[i]\)表示为在第\(i\)位时方案数,转移方程: \[ f[i]=\sum f[j]\;(j< i,sum[i] ...

  6. codeforces 597C (树状数组+DP)

    题目链接:http://codeforces.com/contest/597/problem/C 思路:dp[i][j]表示长度为i,以j结尾的上升子序列,则有dp[i][j]= ∑dp[i-1][k ...

  7. Codeforces 597C. Subsequences (树状数组+dp)

    题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长 ...

  8. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

  9. codeforces 597C C. Subsequences(dp+树状数组)

    题目链接: C. Subsequences time limit per test 1 second memory limit per test 256 megabytes input standar ...

随机推荐

  1. window.loaction.href 不自动跳转的问题

    window.location.href无效/不跳转的原因分析   1.源代码: <a href="javascript:void(0);" onclick="mo ...

  2. 第一本Docker书读书笔记

    日常使用命令 1.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有container的话再加一个指令: ...

  3. 软工+C(10): 团队项目[NABCD] - 对话式编辑

    上一篇:助教指南,持续更新... 下一篇:从命令行开始逐步培养编程能力(Java) 动机(Motivation) Eating your own dog food, also called dogfo ...

  4. iOS 后台调用apns推送

    1.java调用apns推送 2.php 调用apns 推送,可借助终端

  5. docker之常用命令、自定制镜像、公(私)仓库的上传和下载

    一.docker命令 1.参数和命令汇总 1. 参数 Options: --config=~/.docker Location of client config files #客户端配置文件的位置 - ...

  6. 10.4 Vue 父子传值

    简单示例 APP.vue <template> <div> <img :src="imgSrc"> <!-- 父子传值 --> &l ...

  7. P1494 [国家集训队]小Z的袜子

    题目 P1494 [国家集训队]小Z的袜子 解析 在区间\([l,r]\)内, 任选两只袜子,有 \[r-l+1\choose2\] \[=\frac{(r-l+1)!}{2!(r-l-1)!}\] ...

  8. Git让你从入门到精通,看这一篇就够了

    简介 Git 是什么? Git 是一个开源的分布式版本控制系统. 什么是版本控制? 版本控制是一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统. 什么是分布式版本控制系统? 介绍分布 ...

  9. virtualbox虚拟机使用的是桥接网络无法连接外网

    virtualbox虚拟机使用的是桥接网络,获取到的DHCP,无法和外界通信 查看路由表发现有两个默认路由,优先级高的路由指向了,仅主机网络的网关 删除第一个默认路由

  10. Short But Scary 解题报告

    Short But Scary 正解的离线分治+虚树的做法太神奇...搞不到 搞一个菜一点的ddp写写,结果调了200年,下次一定写树剖不写lct了,太难调了... 大概就是按sub2那样维护 你每个 ...