首页 > 其他 > 详细

T3 AT4513 [AGC030D] Inversion Sum

时间:2020-05-31 10:23:59      阅读:26      评论:0      收藏:0      [点我收藏+]

T3 AT4513 [AGC030D] Inversion Sum

题目大意: 给你一个长度为n的数列,然后给你q个交换或不交换操作,你可以选择操作或者不操作,问所有情况下逆序对的总和。

数据范围: n<=3e3 , q<=3e3

期望dp,

先转成期望,再乘上总的情况,设\(dp[i][j]\) 表示 \(i > j\) 的概率,然后具体的转移看代码。。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long LL;
const int N = 3010 , mod = 1e9+7 , inv2 = (mod + 1) / 2;
inline int read()
{
	register int x = 0 , f = 0; register char c = getchar();
	while(c < ‘0‘ || c > ‘9‘) f |= c == ‘-‘ , c = getchar();
	while(c >= ‘0‘ && c <= ‘9‘) x = (x << 3) + (x << 1) + c - ‘0‘ , c = getchar();
	return f ? -x : x;
}
int n , Q;
int a[N] , F[N][N] , G[N][N];

inline int add(int a , int b) { return a + b >= mod ? a - mod + b : a + b; }
inline int mul(int a , int b) { return (LL)a * b % mod; }

int main()
{
	n = read(); Q = read();
	for(int i = 1 ; i <= n ; ++i) a[i] = read();
	for(int i = 1 ; i <= n ; ++i) for(int j = 1 ; j <= n ; ++j) F[i][j] = a[i] > a[j];
	int p1 , p2 , res = 1;
	while(Q--)
	{
		p1 = read(); p2 = read();
		for(int i = 1 ; i <= n ; ++i) if(i != p1 && i != p2)
		{
			G[i][p1] = G[i][p2] = mul(inv2 , add(F[i][p1] , F[i][p2]));
			G[p1][i] = G[p2][i] = mul(inv2 , add(F[p1][i] , F[p2][i]));
		}
		for(int i = 1 ; i <= n ; ++i) if(i != p1 && i != p2) F[i][p1] = G[i][p1] , F[i][p2] = G[i][p2] , F[p1][i] = G[p1][i] , F[p2][i] = G[p2][i];
		F[p1][p2] = F[p2][p1] = mul(inv2 , add(F[p1][p2] , F[p2][p1]));
		res = mul(res , 2);
	}
	int ans = 0;
	for(int i = 1 ; i <= n ; ++i) for(int j = i + 1 ; j <= n ; ++j) ans = add(ans , F[i][j]);
	cout << mul(res , ans) << ‘\n‘;
	return 0;
}

T3 AT4513 [AGC030D] Inversion Sum

原文:https://www.cnblogs.com/R-Q-R-Q/p/12996292.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!