Description
Input
第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子。第2行包含三个整数 N,M,Q ,表示小H希望生成一个1到 N×M 的排列来填入她 N 行 M 列的棋盘,并且小H在初始的 N×M 次交换操作后,又进行了 Q 次额外的交换操作。接下来 Q 行,第 i 行包含两个整数 u_i,v_i,表示第 i 次额外交换操作将交换 T_(u_i )和 T_(v_i ) 的值。
Output
输出一行,包含 N+M-1 个由空格隔开的正整数,表示可以得到的字典序最小的路径序列。
Sample Input
1 3 5 1 71
3 4 3
1 7
9 9
4 9
3 4 3
1 7
9 9
4 9
Sample Output
1 2 6 8 9 12
HINT
本题的空间限制是 256 MB,请务必保证提交的代码运行时所使用的总内存空间不超过此限制。
一个32位整数(例如C/C++中的int和Pascal中的Longint)为4字节,因而如果在程序中声明一个长度为 1024×1024 的32位整型变量的数组,将会占用 4 MB 的内存空间。
2≤N,M≤5000
0≤Q≤50000
0≤a≤300
0≤b,c≤108
0≤x0<d≤108
1≤ui,vi≤N×M
这题因为要求是字典序最小= =所以就可以贪心。一位位取看能不能取到。
取的时候把取的这个数左下右上标记成不可取就行了。
这里放心大单地O(NM)标记。因为每个只会被标记一次所以均摊也就是这个复杂度
【记得找到已经标记过的就直接break】
然后就可以过了
其实还有个难点是数组开不下,要重复利用。标号转换什么的自己推推就好了
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int x[25000001];
int t[5001][5001];
int ans[100001];
int main()
{
long long a,b,c,d;
scanf("%lld%lld%lld%lld%lld",&x[0],&a,&b,&c,&d);
int n,m,q;
scanf("%d%d%d",&n,&m,&q);
int i,j;
int nt=n*m;
for(i=1;i<=nt;i++)
x[i]=(a*x[i-1]*x[i-1]+b*x[i-1]+c)%d;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
t[i][j]=(i-1)*m+j;
int x1,x2;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
int loc=x[(i-1)*m+j]%((i-1)*m+j)+1;
x1=(loc-1)/m+1;
x2=loc-(x1-1)*m;
int tx=t[i][j];
t[i][j]=t[x1][x2];
t[x1][x2]=tx;
}
}
int xx1,yy1,xx2,yy2;
for(i=1;i<=q;i++)
{
scanf("%d%d",&x1,&x2);
xx1=(x1-1)/m+1;
yy1=x1-(xx1-1)*m;
xx2=(x2-1)/m+1;
yy2=x2-(xx2-1)*m;
int tx=t[xx1][yy1];
t[xx1][yy1]=t[xx2][yy2];
t[xx2][yy2]=tx;
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
x[t[i][j]]=(i-1)*m+j;
memset(t,0,sizeof(t));
int xx=0,yy=0;
int p=0;
int ii,jj;
int ss,tt;
for(i=1;i<=nt;i++)
{
xx=(x[i]-1)/m+1;
yy=x[i]-(xx-1)*m;
if(t[xx][yy]!=0)
continue;
p++;
ans[p]=i;
if(p==n+m-1)
break;
ss=1;
tt=yy-1;
for(ii=xx+1;ii<=n;ii++)
{
if(t[ii][tt]!=0)
break;
for(jj=tt;jj>=ss;jj--)
{
if(t[ii][jj]!=0)
{
ss=jj+1;
break;
}
t[ii][jj]=1;
}
if(ss>tt)
break;
}
ss=yy+1;
tt=m;
for(ii=xx-1;ii>=1;ii--)
{
if(t[ii][ss]!=0)
break;
for(jj=ss;jj<=tt;jj++)
{
if(t[ii][jj]!=0)
{
tt=jj-1;
break;
}
t[ii][jj]=1;
}
if(ss>tt)
break;
}
}
for(i=1;i<=p-1;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[i]);
return 0;
}