您的位置:首页 > 其它

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

2016-05-11 17:16 489 查看
【题目链接】

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

大概是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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: