It is too difficult to explain. Read the PDF by yourself ..
Train of Thought: First process the array according to the method described in it, and then in order to make the series contain as many small numbers as possible, so 1 must appear, in this way, the Lexicographic Order of the entire sequence can be minimized. We think that if 2 can also be in this series, it would be better, but 2 may not be in this series, that is, if 2 is in a place where 1 is not feasible, it cannot go to 2. Therefore, we can enumerate numbers from small to large. If the current number can go, we will output the number and mark all nodes that cannot go after this node. The space is tight. 5000*5000 can be used to open int * 2 + bool * 1. The limit is reached ..
Code:
#include <cstdio>#include <algorithm>#define MAX 5010using namespace std; long long seed,a,b,c,d;int arr[MAX * MAX],map[MAX][MAX];bool v[MAX][MAX];int ans[MAX << 1];int m,n,asks; inline int GetX(); int main(){ scanf("%lld%lld%lld%lld%lld%d%d%d",&seed,&a,&b,&c,&d,&m,&n,&asks); for(int i = 1;i <= m * n; ++i) arr[i] = i,swap(arr[i],arr[GetX() % i + 1]); for(int x,y,i = 1;i <= asks; ++i) { scanf("%d%d",&x,&y); swap(arr[x],arr[y]); } for(int i = 1;i <= m; ++i) for(int j = 1;j <= n; ++j) map[i][j] = arr[(i - 1) * n + j]; for(int i = 1;i <= m; ++i) for(int j = 1;j <= n; ++j) arr[map[i][j]] = (i - 1) * n + j; for(int i = 1;i <= m * n; ++i) { int x = arr[i] / n + 1 - (arr[i] % n == 0); int y = arr[i] - (x - 1) * n; if(!v[x][y]) { if(i != 1) putchar(' '); printf("%d",i); for(int j = x + 1;j <= m; ++j) for(int k = y - 1;k > 0; --k) { if(v[j][k]) break; v[j][k] = true; } for(int j = x - 1;j > 0; --j) for(int k = y + 1;k <= n; ++k) { if(v[j][k]) break; v[j][k] = true; } } } return 0;} inline int GetX(){ return seed = (a * seed * seed % d + b * seed % d + c) % d;}
Bzoj 3671 Noi 2014 random number generator greedy