【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=3671
http://uoj.ac/problem/6
【题解】
首先求出X的数列,这是这道题的难点(?),要注意尽量少取模。
接下来就简单了,从小到大枚举每个数,用贪心的策略选取,并把这个数的左下和右上方的所有数标记为不可选取,注意一旦标记到的数已经不可取了,那么直接退出循环,这样才能保证复杂度。
时间复杂度
O(N∗M)
O
(
N
∗
M
)
【代码】
/* - - - - - - - - - - - - - - -
User : VanishD
problem :
Points :
- - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - -
User : VanishD
problem : [bzoj3671][uoj6][noi2014]
Points : read?
- - - - - - - - - - - - - - - */
# include <bits/stdc++.h>
# define ll long long
# define inf 0x3f3f3f3f
# define N 5010
using namespace std;
int read(){
int tmp = 0, fh = 1; char ch = getchar();
while (ch < '0' || ch > '9'){ if (ch == '-') fh = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9'){ tmp = tmp * 10 + ch - '0'; ch = getchar(); }
return tmp * fh;
}
int mp[N][N], n, m, q, ans[N * 2], ansnum, p[N * N], canx[N], cany[N];
int main(){
// freopen(".in", "r", stdin);
// freopen("A.out", "w", stdout);
ll x = read(), a = read(), b = read(), c = read(), d = read();
n = read(), m = read(), q = read();
for (int i = 1, nowx = 1, nowy = 1; i <= n * m; i++){
x = (a * x * x + b * x + c) % d;
mp[nowx][nowy] = i;
int y = x % i + 1;
int tmpx = (y - 1) / m + 1, tmpy = (y - 1) % m + 1;
swap(mp[tmpx][tmpy], mp[nowx][nowy]);
nowy++;
if (nowy > m) nowx++, nowy = 1;
}
for (int i = 1; i <= q; i++){
int tmp1 = read(), tmp2 = read(),
tx1 = (tmp1 - 1) / m + 1, tx2 = (tmp2 - 1) / m + 1,
ty1 = (tmp1 - 1) % m + 1, ty2 = (tmp2 - 1) % m + 1;
swap(mp[tx1][ty1], mp[tx2][ty2]);
}
// for (int i = 1; i <= n; i++)
// for (int j = 1; j <= m; j++)
// printf("%d%c", mp[i][j], (j == m) ? '\n' : ' ');
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
p[mp[i][j]] = (i - 1) * m + j;
for (int i = 1; i <= n; i++)
canx[i] = 0, cany[i] = m + 1;
for (int i = 1; i <= n * m; i++){
int x = (p[i] - 1) / m + 1, y = (p[i] - 1) % m + 1;
if (canx[x] < y && cany[x] > y){
ans[++ansnum] = i;
for (int tx = x + 1; tx <= n; tx++){
if (canx[tx] >= y - 1) break;
canx[tx] = y - 1;
}
for (int tx = x - 1; tx >= 1; tx--){
if (cany[tx] <= y + 1) break;
cany[tx] = y + 1;
}
}
}
for (int i = 1; i <= ansnum; i++)
printf("%d%c", ans[i], (i == ansnum) ? '\n' : ' ');
return 0;
}