题目链接

题意:

对于长度为$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. 错误ERROR datanode.DataNode (DataXceiver.java:run(278)) - hadoop07:50010DataXceiver error processing unknown operation src:127.0.0.136479 dst:127.0.0.150010

    原因: Ambari 每分钟会向datanode发送"ping"连接一下去确保datanode是正常工作的.否则它会触发alert.但是datanode并没有处理空内容的逻辑,所以 ...

  2. LoadRunner 11 error:Cannot initialize driver dll

    LoadRunner 11 error:Cannot initialize driver dll 这个错误很容易解决,使用win7系统时,有些程序要以管理员身份才能运行. 解决方案:右键选择:“以管理 ...

  3. Angular5 路由守卫

    今年下半年一直很忙,没有多少时间来写博客,很多笔记都记在了本地一起提交到了git上边. 夏末的时候做的两个vue项目中有接触到vue的路由守卫,今天在另外一个angular上,发现路由守卫有异常,导致 ...

  4. Linux-基础学习(二)-基本部署

    开始今日份整理 1. 系统优化部分 1.1 Linux防火墙安全相关(重要) 1.1.1 SELinux功能 SELinux(Security-Enhanced Linux) 是美国国家安全局(NSA ...

  5. 基于Armitage的MSF自动化集成攻击实践

    基于Armitage的MSF自动化集成攻击实践 目录 0x01 实践环境 0x02 预备知识 0x03 Armitage基础配置 0x04 Nmap:Armitage下信息搜集与漏洞扫描 0x05 A ...

  6. 混合编程[python+cpp+cuda]

    很多时候,我们是基于python进行模型的设计和运行,可是基于python本身的速度问题,使得原生态python代码无法满足生产需求,不过我们可以借助其他编程语言来缓解python开发的性能瓶颈.这里 ...

  7. Java 200+ 面试题补充③ Dubbo 模块

    昨天在我的 Java 面试粉丝群里,有一个只有一年开发经验的小伙伴只用了三天时间,就找到了一个年薪 20 万的工作,真是替他感到开心. 他的经历告诉我们:除了加强自我实战经验之外,还要努力积累自己的理 ...

  8. CentOS自定义快捷键,以终端为例

    和Ubuntu不同的是,CentOS默认情况下没有Terminal的快捷键.因此,用户需要自定义. 具体操作: 一.打开设置,搜索keyboard 二.点击+号定义快捷键 名称随意填,查询终端程序所在 ...

  9. Python进阶5---StringIO和BytesIO、路径操作、OS模块、shutil模块

    StringIO StringIO操作 BytesIO BytesIO操作 file-like对象 路径操作 路径操作模块 3.4版本之前:os.path模块 3.4版本开始 建议使用pathlib模 ...

  10. ckeditor,关于数据回显