题目链接

题意:

对于长度为$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. C# 里面swith的或者

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

  2. 数据类型:list列表[]、元祖tuple()、dict字典{}

    List 列表[] 可变的 lst = [1,2,3,4] #改 lst[(元素下标)] = '需要修改的' #通过下表修改 lst[下标:下标] = '需要修改的' #通过范围修改 #加 lst.a ...

  3. Google Chrome等浏览器不允许关闭点击跟踪??

    hrome.Safari.Opera 和 Microsoft Edge 的新版本将不再允许用户关闭“链接审计( hyperlink auditing)”的功能.链接审计是一项 HTML 标准,被用于跟 ...

  4. TensorRT&Sample&Python[uff_custom_plugin]

    本文是基于TensorRT 5.0.2基础上,关于其内部的uff_custom_plugin例子的分析和介绍. 本例子展示如何使用cpp基于tensorrt python绑定和UFF解析器进行编写pl ...

  5. Python--day01(计算机基础)

    Python: python 是一门面向后台的编程语言,在大数据,数据分析,机器学习,人工智能,爬虫,自动化运维,web等方面具有强大功能. 基础阶段学习内容:基本语法,文件处理,函数,模块,面向对象 ...

  6. flask(二)之Jinja2模板与Flask-WTF

    01-文档 官方文档:http://docs.jinkan.org/docs/jinja2/ 02-基本语义 Jinja2做构成的模板文件中,文本内容大致可以分成几个种类.比如特殊文本(不进行转义,比 ...

  7. golang lua使用示例

    package main import ( "fmt" "github.com/yuin/gopher-lua" ) func hello(L *lua.LSt ...

  8. RBAC权限管理模型 产品经理 设计

    RBAC权限管理模型:基本模型及角色模型解析及举例 | 人人都是产品经理http://www.woshipm.com/pd/440765.html RBAC权限管理 - PainsOnline的专栏 ...

  9. 如何批量修改网页 更新网站 一键保存 windows查看和排序

    批量打开需要修改的网页,一键保存:一个网站会由很多网页组成,当需要大量更新的时候,如果一个个进行打开修改,效率会很低,内容修改不多,且容易修改的时候,可以用editplus这种小编辑软件批量打开,批量 ...

  10. java基础3之IO

    流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接.类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流. 流的种类 字符 ...