https://www.luogu.org/problemnew/show/P4223

期望乘以\(\binom {n}{2}^k\)变成了计数问题

我们考虑每一组数\((A, B)\)产生的贡献CCCCCACCCCBCCCC

分7组考虑\((A, B)\)在\(k\)次操作之后去哪里了

\((A, B)\; (A, C)\;(B,A)\;(B,C)\;(C,A)\;(C,B)\;(C,C)\)

可以列出一个\(7 \times 7\)的矩阵表

矩阵快速幂后表示转移\(k\)次之后的系数(有点恶心

有一个结论就是CCCACCCBCCC

对于比如\((A, C)\)这个状态

\(B\)到达\(A\)左边和到达\(B\)右边的方案数是和\(C\)的个数成正比的

数学归纳法可证

因此推出式子可以发现\(i\)对\(j>i\)的贡献是一样的

树状数组维护即可

复杂度\(\mathcal O(n\log n)\)

#include <bits/stdc++.h>
#define int long long
#define fo(i, n) for(int i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
x = 0;char c = getchar(); bool f = 0;
for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
if(f) x = -x;
}
const int N = 5e5 + 233;
namespace {
const int mo = 1e9 + 7;
inline int add(int u, int v) {
if((u += v) >= mo) u -= mo;
return u;
}
inline int sub(int u, int v) {
if((u -= v) < 0) u += mo;
return u;
}
inline int mul(int u, int v) {
return u * v % mo;
}
inline int pw(int a, int k, int mo) {
int ans = 1;
for(; k; k >>= 1, a = mul(a, a))
if(k & 1) ans = mul(ans, a);
return ans;
}
}
struct Mar {
int m[7][7];
Mar() {
memset(m, 0, sizeof m);
}
inline void E(void) {
for(int i = 0; i < 7; i ++)
m[i][i] = 1;
}
}f, ans;
int a[N];
int cnt = 0, n, K;
Mar operator * (Mar a, Mar b) {
Mar c;
for(int i = 0; i < 7; i ++)
for(int j = 0; j < 7; j ++) {
int t = 0;
for(int k = 0; k < 7; k ++)
t = add(t, mul(a.m[i][k], b.m[k][j]));
c.m[i][j] = t;
}
return c;
} inline void I(int a, int b, int c, int d, int e, int g, int h) {
f.m[cnt][0] = a; f.m[cnt][1] = b; f.m[cnt][2] = c;
f.m[cnt][3] = d; f.m[cnt][4] = e; f.m[cnt][5] = g;
f.m[cnt][6] = h;
cnt ++;
} inline void Matrix_Init(void) {
int t = (n - 2) * (n - 3) / 2 % mo;
I(t, n - 2, 1, 0, 0, n - 2, 0);
I(1, t + n - 3, 0, 1, 1, 0, n - 3);
I(1, 0, t, n - 2, n - 2, 0, 0);
I(0, 1, 1, t + n - 3, 0, 1, n - 3);
I(0, 1, 1, 0, t + n - 3, 1, n - 3);
I(1, 0, 0, 1, 1, t + n - 3, n - 3);
I(0, 1, 0, 1, 1, 1, t + 2 * (n - 4) + 1);
} inline Mar mf(Mar a, int k) {
Mar ans; ans.E();
for(; k; k >>= 1, a = a * a)
if(k & 1) ans = ans * a;
return ans;
} struct Bit {
int tr[N], n;
inline void init(void) {
memset(tr, 0, sizeof tr);
n = ::n;
}
inline void A(int u, int val) {
for(; u <= n; u += u & -u)
tr[u] = add(tr[u], val);
}
inline int Q(int u) {
int ans = 0;
for(; u >= 1; u -= u & -u)
ans = add(ans, tr[u]);
return ans;
}
}x, y, z; inline void doit(void) {
x.init(); y.init(); z.init();
int p = pw(n - 2, mo - 2, mo);
int inv2 = pw(2, mo - 2, mo);
int res = mul(n * (n - 1) / 2 % mo, ans.m[0][6]);
res = mul(res, inv2);
for(int j = 1; j <= n; j ++) {
int t;
int sm = x.Q(a[j] - 1);
int la = j - 1 - sm;
int p1 = add(mul(ans.m[0][3], mul(n - j, p)), mul(ans.m[0][5], mul(j - 2, p)));
int p2 = add(mul(ans.m[0][3], mul(j - 2, p)), mul(ans.m[0][5], mul(n - j, p)));
res = add(res, add(mul(la, p1), mul(sm, p2))); res = add(res, add(mul(la, ans.m[0][0]),
mul(sm, ans.m[0][2])));
res = add(res, add(sub(y.Q(n), y.Q(a[j])), z.Q(a[j] - 1))); x.A(a[j], 1); t = add(mul(ans.m[0][1], mul(n - j - 1, p)),
mul(ans.m[0][4], mul(j - 1, p)));
y.A(a[j], t); t = add(mul(ans.m[0][1], mul(j - 1, p)),
mul(ans.m[0][4], mul(n - j - 1, p)));
z.A(a[j], t);
}
cout << res << "\n";
} main(void) {
read(n); read(K);
fo(i, n) read(a[i]);
Matrix_Init();
ans = mf(f, K);
doit();
}

计数 luogu 4223 期望逆序对的更多相关文章

  1. Luogu P4280 [AHOI2008]逆序对

    题目描述 甩个链接就走 题解 先预处理出每个位置上分别填上 1~k 的数的逆序对的数量的前缀和与后缀和 (不用管原来有值的,统计时不计入答案就行了) (有点绕,看代码应该能懂) 然后枚举每个 -1 的 ...

  2. BZOJ5058 期望逆序对 【矩乘 + 组合数学 + 树状数组】

    题目链接 BZOJ5058 题解 可以发现任意两个位置\(A,B\)最终位置关系的概率是相等的 如果数列是这样: CCCCACCCCBCCCC 那么最终有\(7\)种位置关系 \((A,B)\) \( ...

  3. Wannafly Camp 2020 Day 1A 期望逆序对 - 概率期望

    分类讨论即可 #include <bits/stdc++.h> using namespace std; #define int long long const int N = 5005; ...

  4. luogu P1966 火柴排队 (逆序对)

    luogu P1966 火柴排队 题目链接:https://www.luogu.org/problemnew/show/P1966 显然贪心的想,排名一样的数相减是最优的. 证明也很简单. 此处就不证 ...

  5. [BZOJ 3295] [luogu 3157] [CQOI2011]动态逆序对(树状数组套权值线段树)

    [BZOJ 3295] [luogu 3157] [CQOI2011] 动态逆序对 (树状数组套权值线段树) 题面 给出一个长度为n的排列,每次操作删除一个数,求每次操作前排列逆序对的个数 分析 每次 ...

  6. luogu 1521-求逆序对

    题意: 逆序对指在一个序列中ai>aj && i < j,也就是一前一后两个数,当大的在前面的时候即算一对. 题目求在一个由1-n组成的序列中逆序对为k的序列的个数. 出题 ...

  7. luogu 1966 火柴排队 离散化+逆序对

    题意:找到最小改变对数使a数组的第i大和b数组的第i大相等 则先将a,b,数组编号再排序,则数组显示的就是排名第i的数的编号 再关键一步:c[a[i].id]=b[i].id 实质上就是新建一个数组, ...

  8. 【Luogu】P3157动态逆序对(树状数组套主席树)

    题目链接 md第一道在NOILinux 下用vim做的紫题.由于我对这个操作系统不是很熟悉,似乎有什么地方搞错了,md调死.(我还打了两遍代码,调了两个小时) 但是这道题并不难,就是树状数组套上主席树 ...

  9. [LUOGU] P1908 逆序对

    题目描述 猫猫TOM和小老鼠JERRY最近又较量上了,但是毕竟都是成年人,他们已经不喜欢再玩那种你追我赶的游戏,现在他们喜欢玩统计.最近,TOM老猫查阅到一个人类称之为"逆序对"的 ...

随机推荐

  1. zipkin的安装与搭建

    下载与部署 jar中yaml文件配置 启动传入并参数 web界面 目录 zipkin是分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪. 下载与部署 wget -O zipki ...

  2. Java CPU占用过高问题排查,windows和Linux

    LINUX系统: linux系统比较简单: 1.使用命令 ps -ef | grep 找出异常java进程的pid.  找出pid为 20189 2. top -H -p 20189,所有该进程的线程 ...

  3. error C2338: You've instantiated std::aligned_storage<Len, Align> with an extended alignment (in other words, Align >

    报的完整错误为: error C2338: You've instantiated std::aligned_storage<Len, Align> with an extended al ...

  4. ElementUI 源码定制防坑指南

    背景 我司OA系统公文管理模块Office在线编辑使用的是金格IWebOffice中间件[PPAPI插件,通过<object>标签加载],IWebOffice在chrome中设置div盒子 ...

  5. canvas炫酷时钟

    canvas炫酷时钟 实现的功能 主要用到canvas的一些基础api 直接看效果 html: <canvas id="myCanvas" width="500&q ...

  6. CSS 实现盒子水平居中、垂直居中和水平垂直居中的方法

     CSS 实现盒子模型水平居中 水平居中效果图如下: HTML: CSS 全局样式: 方法一:使用margin: 0 auto;(只适用于子盒子有宽的时候) 方法二:text-align + disp ...

  7. “proxy” in package.json must be a string 解决办法

    今天学习一个react项目.想从本地服务器获取数据. 直接axios.get('http://localhost:80/api/react/header.json'),报错跨域. 网上查了下,需要在p ...

  8. C++线程同步与互斥总结

    互斥:当多个线程访问同一个全局变量,或者同一个资源(比如打印机)的时候,需要进行线程间的互斥操作来保证访问的安全性. 临界区.互斥体.事件和信号量都可以实现线程互斥.但如果仅仅需要实现互斥功能,推荐前 ...

  9. 笔谈OpenGL ES(三)

    昨天下午以及今天一天,公司安排了新员工培训课程,占用了自己的一些时间,但是也了解到一些新的有利于自身的东西.进公司就要进有完善公司体系和制度的公司,小公司真的是没搞头的,我体验过,反正小公司以后是不会 ...

  10. VLAN实验3:理解Hybrid接口的应用

    实验环境 实验拓扑图 实验编址 实验步骤1.基本配置按照实验编址为PC配置IP地址,以PC5为例 在PC5与PC1通过ping命令测试,发现通讯正常.(以此为例,其他的我就不一一截图测试了.) 在S1 ...