【BZOJ3671】[Noi2014]随机数生成器【模拟】【贪心】【卡空间】

【题目链接】

一眼模拟+贪心,算了算复杂度,好像不太对呀...

大概是O(n * m + Q + n + m + 1 + n * m)。。

嘿嘿嘿。

/* Telekinetic Forest Guard */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int maxn = 5001, maxm = maxn * maxn;

int n, m, k, Q, g[maxn][maxn], X[maxm];
bool vis[maxn][maxn];

template <class nt>
inline void read(nt &x) {
	bool f = 0; x = 0; char ch = getchar();
	for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? 1 : 0;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	if(f) x = -x;
}

LL x0, a, b, c, d;

inline int rd() {
	return x0 = (x0 * (a * x0 + b) + c) % d;
}

int main() {
	read(x0); read(a); read(b); read(c); read(d);
	read(n); read(m); read(Q); k = n * m;
	for(int i = 1; i <= k; i++) X[i] = i, swap(X[i], X[rd() % i + 1]);
	for(int i = 1; i <= Q; i++) {
		int u, v; read(u); read(v);
		swap(X[u], X[v]);
	}
	for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) g[i][j] = X[(i - 1) * m + j];
	for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) X[g[i][j]] = (i - 1) * m + j;

	int tot = 0;
	for(int i = 1; i <= k; i++) {
		int x = (X[i] - 1) / m + 1, y = X[i] - (x - 1) * m;
		if(!vis[x][y]) {
			tot++;
			printf("%d%c", i, " \n"[tot == n + m - 1]);
			if(tot == n + m - 1) break;
			for(int j = x + 1; j <= n; j++) for(int t = y - 1; t; t--) if(!vis[j][t]) vis[j][t] = 1; else break;
			for(int t = y + 1; t <= m; t++) for(int j = x - 1; j; j--) if(!vis[j][t]) vis[j][t] = 1; else break;
		}
	}

	return 0;
}


你可能感兴趣的:(【BZOJ3671】[Noi2014]随机数生成器【模拟】【贪心】【卡空间】)