zoukankan      html  css  js  c++  java
  • BZOJ5058 期望逆序对 【矩乘 + 组合数学 + 树状数组】

    题目链接

    BZOJ5058

    题解

    可以发现任意两个位置(A,B)最终位置关系的概率是相等的
    如果数列是这样:
    CCCCACCCCBCCCC
    那么最终有(7)种位置关系
    ((A,B))
    ((A,C))
    ((B,A))
    ((B,C))
    ((C,A))
    ((C,B))
    ((C,C))
    手玩出(7 imes 7)的转移矩阵,矩乘后即可得到各种位置关系的概率
    然后枚举(B),用树状数组维护与(A)有关的量组合计算即可
    写得极烦
    放开我我没疯
    我只是计数时把大小弄反了

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    #define lbt(x) (x & -x)
    using namespace std;
    const int maxn = 500005,maxm = 100005,INF = 0x3f3f3f3f,P = 1000000007;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    struct Matrix{
    	int s[7][7],n,m;
    	Matrix(){cls(s,0); n = m = 0;}
    }M,F0,F;
    inline Matrix operator *(const Matrix& a,const Matrix& b){
    	Matrix c;
    	if (a.m != b.n) return c;
    	c.n = a.n; c.m = b.m;
    	for (int i = 0; i < c.n; i++)
    		for (int j = 0; j < c.m; j++)
    			for (int k = 0; k < a.m; k++)
    				c.s[i][j] = (c.s[i][j] + 1ll * a.s[i][k] * b.s[k][j] % P) % P;
    	return c;
    }
    inline Matrix qpow(Matrix a,LL b){
    	Matrix re; re.n = re.m = a.n;
    	for (int i = 0; i < re.n; i++) re.s[i][i] = 1;
    	for (; b; b >>= 1,a = a * a)
    		if (b & 1) re = re * a;
    	return re;
    }
    inline int qpow(int a,int b){
    	int re = 1;
    	for (; b; b >>= 1,a = 1ll * a * a % P)
    		if (b & 1) re = 1ll * re * a % P;
    	return re;
    }
    inline void Add(int& x,int y){x += y; x >= P ? x -= P : 0;}
    int n,K,A[maxn];
    void init(int* a,int A,int B,int C,int D,int E,int F,int G){
    	a[0] = A; a[1] = B; a[2] = C; a[3] = D; a[4] = E; a[5] = F; a[6] = G;
    }
    void cal(){
    	M.n = M.m = 7;
    	int a = 1ll * (n - 2) * (n - 3) / 2 % P,b = ((1ll * n * (n - 1) / 2 % P - n) % P + P) % P;
    	int c = n - 2,d = n - 3,e = ((1ll * n * (n - 1) / 2 % P - 4) % P + P) % P;
    	init(M.s[0],a,1,1,0,0,1,0);
    	init(M.s[1],c,b,0,1,1,0,1);
    	init(M.s[2],1,0,a,1,1,0,0);
    	init(M.s[3],0,1,c,b,0,1,1);
    	init(M.s[4],0,1,c,0,b,1,1);
    	init(M.s[5],c,0,0,1,1,b,1);
    	init(M.s[6],0,d,0,d,d,d,e);
    	F0.n = 7; F0.m = 1; F0.s[0][0] = 1;
    	F = qpow(M,K) * F0;
    }
    int s[maxn],pos[maxn],vpos[maxn];
    void add(int* s,int u,int v){while (u <= n) s[u] = (s[u] + v) % P,u += lbt(u);}
    int query(int* s,int u){int re = 0; while (u) re = (re + s[u]) % P,u -= lbt(u); return re;}
    void work(){
    	int ans = 0;
    	int p1 = F.s[0][0],p2 = F.s[1][0],p3 = F.s[2][0],p4 = F.s[3][0];
    	int p5 = F.s[4][0],p6 = F.s[5][0],p7 = F.s[6][0],inv = qpow(n - 2,P - 2);
    	int inv2 = qpow(2,P - 2);
    	LL sumf = 0,sumg = 0,a,b,fa,fb,ga,gb;
    	for (int i = 1; i <= n; i++){
    		a = query(s,A[i]); fa = query(pos,A[i]); ga = query(vpos,A[i]); 
    		b = i - 1 - a; fb = sumf - fa,gb = sumg - ga;
    		Add(ans,1ll * b * p1 % P);
    		Add(ans,(1ll * a * (n - i) % P + 1ll * b * (i - 2) % P) * inv % P * p2 % P);
    		Add(ans,1ll * a * p3 % P);
    		Add(ans,1ll * (fb + ga) % P * inv % P * p4 % P);
    		Add(ans,(1ll * a * (i - 2) % P + 1ll * b * (n - i) % P % P) % P * inv % P * p5 % P);
    		Add(ans,1ll * (gb + fa) % P * inv % P * p6 % P);
    		add(s,A[i],1); add(pos,A[i],i - 1); add(vpos,A[i],n - i - 1);
    		sumf += i - 1; sumg += n - i - 1;
    	}
    	Add(ans,1ll * n * (n - 1) / 2 % P * inv2 % P * p7 % P);
     	printf("%d
    ",(ans % P + P) % P);
    }
    int main(){
    	n = read(); K = read();
    	REP(i,n) A[i] = read();
    	cal();
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    Oracle Instant Client 配置
    释放至强平台 AI 加速潜能 汇医慧影打造全周期 AI 医学影像解决方案
    Analytics Zoo Cluster Serving自动扩展分布式推理
    基于时序数据,推动智能运维发展
    助力用户选择更优模型和架构,推动 AI机器视觉落地智能制造
    英特尔与 Facebook 合作采用第三代英特尔® 至强® 可扩展处理器和支持 BFloat16 加速的英特尔® 深度学习加速技术,提高 PyTorch 性能
    如何无缝地将人工智能扩展到分布式大数据
    Burger King使用RayOnSpark进行基于实时情景特征的快餐食品推荐
    如何往Spark社区做贡献,贡献代码
    开源:从社区到商业化
  • 原文地址:https://www.cnblogs.com/Mychael/p/9284185.html
Copyright © 2011-2022 走看看