IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【模拟赛】随机跳走(消元,高斯消元) -> 正文阅读

[数据结构与算法]【模拟赛】随机跳走(消元,高斯消元)

题面

在这里插入图片描述
样例输入

3 1
512962164 361666497
363881557 376525373
176039948 197582789

样例输出

510253268
277873211
210117875

在这里插入图片描述
512mb,2s 。

题解

由于数据全随机,所以其实在哪里出发都一样,最终出发点的影响一定会消失。每个点停留的概率会趋于稳定,而最终的稳定值,满足转移一次后概率不变。

那么,我们通过状态转移 d p i ? l i , j , d p i ? r i , j ?? → ? d p k dp_i*l_{i,j},dp_i*r_{i,j}~~\rightarrow~dp_k dpi??li,j?,dpi??ri,j????dpk? 的矩阵可以高斯消元求出原来的 d p i dp_i dpi? 。如果仅通过这 n n n 个方程消元,必定会得到 n n n 个 0,我们需要再加一个方程 ∑ d p i = 1 \sum dp_i=1 dpi?=1

于是我们可以得到一个 O ( n 3 ) O(n^3) O(n3) 的做法,可以通过 2 k ≥ n 2k\geq n 2kn 的数据。

接下来我们发现, k k k 非常小,因此可以带状高斯消元。但是带状高斯消元常数过大,且 n n n 过大时不方便存储。其实我们可以先手动消元。

我们假定前 2 k 2k 2k 个数是未知变元,可以通过这 2 k 2k 2k 个数的线性组合表示出第 2 k + 1 2k+1 2k+1 个数,进而表示所有后面的变元。然后我们再根据这些线性组合的信息写出前 2 k 2k 2k 个数的 2 k 2k 2k 个方程加上方程 ∑ d p i = 1 \sum dp_i=1 dpi?=1 ,就可以进行高斯消元了。

需要注意的是,每一个 l i , j , r i . j l_{i,j},r_{i.j} li,j?,ri.j? 都必须被用上,且 n ≤ 2 k n\leq 2k n2k 要特判。时间复杂度 O ( n k 2 ) O(nk^2) O(nk2) ,瓶颈在于求出每个数的线性组合表示。

CODE

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<random>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 20005
#define LL long long
#define ULL unsigned long long
#define ENDL putchar('\n')
#define DB double
#define lowbit(x) (-(x) & (x))
#define FI first
#define SE second
#define eps 1e-9
int xchar() {
	static const int maxn = 1000000;
	static char b[maxn];
	static int pos = 0,len = 0;
	if(pos == len) pos = 0,len = fread(b,1,maxn,stdin);
	if(pos == len) return -1;
	return b[pos ++];
}
//#define getchar() xchar()
LL read() {
	LL f = 1,x = 0;int s = getchar();
	while(s < '0' || s > '9') {if(s<0)return -1;if(s=='-')f=-f;s = getchar();}
	while(s >= '0' && s <= '9') {x = (x<<1) + (x<<3) + (s^48);s = getchar();}
	return f*x;
}
void putpos(LL x) {if(!x)return ;putpos(x/10);putchar((x%10)^48);}
void putnum(LL x) {
	if(!x) {putchar('0');return ;}
	if(x<0) putchar('-'),x = -x;
	return putpos(x);
}
void AIput(LL x,int c) {putnum(x);putchar(c);}

const int MOD = 998244353;
int n,m,s,o,k;
int qkpow(int a,int b) {
	int res = 1;
	while(b>0) {
		if(b & 1) res = res *1ll* a % MOD;
		a = a *1ll* a % MOD; b >>= 1;
	}return res;
}
int l[MAXN][55],r[MAXN][55];
int b[105],kk[MAXN][105];
int a[305][305];
void Gauss(int n) {
	for(int i = 0;i < n;i ++) {
		for(int j = i+1;j <= n;j ++) {
			if(a[j][i]) {swap(a[i],a[j]);break;}
		}
		int iv = qkpow(a[i][i],MOD-2);
		for(int j = i;j <= n;j ++) a[i][j] = a[i][j] *1ll* iv % MOD;
		for(int j = 0;j <= n;j ++) {
			if(j == i || !a[j][i]) continue;
			for(int k = n;k >= i;k --) {
				(a[j][k] += MOD-a[i][k]*1ll*a[j][i]%MOD) %= MOD;
			}
		}
	}return ;
}
int main() {
	n = read(); m = read();
	for(int i = 0;i < n;i ++) {
		int su = 0;
		for(int j = m;j > 0;j --) {
			l[i][j] = read();
			(su += l[i][j]) %= MOD;
		}
		for(int j = 1;j <= m;j ++) {
			r[i][j] = read();
			(su += r[i][j]) %= MOD;
		}
		l[i][0] = MOD-1;
		su = qkpow(su,MOD-2);
		for(int j = 1;j <= m;j ++) {
			l[i][j] = l[i][j] *1ll* su % MOD;
			r[i][j] = r[i][j] *1ll* su % MOD;
		}
	}
	if(2*m >= n) {
		for(int i = 0;i < n;i ++) {
			(a[i][i] += MOD-1) %= MOD;
			for(int j = 1;j <= m;j ++) {
				(a[(i+n-j)%n][i] += l[i][j]) %= MOD;
				(a[(i+j)%n][i] += r[i][j]) %= MOD;
			}
		}
		for(int i = 0;i <= n;i ++) a[n][i] = 1;
		Gauss(n);
		for(int i = 0;i < n;i ++) AIput(a[i][n],'\n');
		return 0;
	}
	for(int i = 0;i < m;i ++) b[i] = i,kk[i][i] = 1;
	for(int i = n-m;i < n;i ++) b[m+n-i-1] = i,kk[i][m+n-i-1] = 1;
	for(int i = m;i < n-m;i ++) {
		int iv = qkpow(l[i][m],MOD-2),p = i-m;
		for(int j = 0;j < m;j ++) {
			int y = (p+j)%n;
			int xs = l[y][j]*1ll*iv%MOD;
			for(int k = 0;k < 2*m;k ++) {
				kk[i][k] = (kk[y][k]*1ll*xs + kk[i][k]) % MOD;
			}
		}
		for(int j = 1;j <= m;j ++) {
			int y = (p+n-j)%n;
			int xs = r[y][j]*1ll*iv%MOD;
			for(int k = 0;k < 2*m;k ++) {
				kk[i][k] = (kk[y][k]*1ll*xs + kk[i][k]) % MOD;
			}
		}
		for(int j = 0;j < 2*m;j ++) kk[i][j] = (MOD-kk[i][j]) % MOD;
	}
	for(int i = 0;i < 2*m;i ++) {
		int x = b[i];
		int iv = qkpow(l[x][m],MOD-2),p = (x+n-m)%n;
		a[i][i] = 1;
		for(int j = 0;j < m;j ++) {
			int y = (p+j)%n;
			int xs = l[y][j]*1ll*iv%MOD;
			for(int k = 0;k < 2*m;k ++) {
				a[i][k] = (kk[y][k]*1ll*xs + a[i][k]) % MOD;
			}
		}
		for(int j = 1;j <= m;j ++) {
			int y = (p+n-j)%n;
			int xs = r[y][j]*1ll*iv%MOD;
			for(int k = 0;k < 2*m;k ++) {
				a[i][k] = (kk[y][k]*1ll*xs + a[i][k]) % MOD;
			}
		}
	}
	for(int i = 0;i < n;i ++) {
		for(int j = 0;j < 2*m;j ++) {
			a[m<<1][j] = (kk[i][j] + a[m<<1][j]) % MOD;
		}
	}
	a[m<<1][m<<1] = 1;
	Gauss(m<<1);
	for(int i = 0;i < n;i ++) {
		int as = 0;
		for(int j = 0;j < 2*m;j ++) {
			(as += a[j][m<<1]*1ll*kk[i][j]%MOD) %= MOD;
		}
		AIput(as,'\n');
	}
	return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:50:47  更:2022-03-10 22:55:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 13:37:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码