疯狂的涂色
小t非常喜爱画画,但是他还是一个初学者。他最近费尽千辛万苦才拜到小Q为师。小Q是画鸡蛋长大的,让小t一入门就拿着一张白纸条疯狂地涂色。假设纸条被划分成了n个区域,用1~n的整数从左到右顺序编号,小Q总共下达了m条指令。第i条指令是让小t把编号为(i*p+q)mod n+1与(i*q+p)mod n+1 (p,q为常整数)之间的区域(连续的一段区域)涂成第i种颜色。
现在由于小Q下达的指令过多,小t一时应付不过来。小Q只让他回答每一个区域最后的颜色。趁小Q还在“五谷轮回之所”忙碌时,小t偷偷的请让你这个计算机高手帮他算出最后的颜色状态,并告诉他。
输入格式
文件仅一行,为四个整数n,m,p,q。
输出格式
文件共n行,第i行代表最后第i个格子的颜色。白色编号为0。
输入样例
4 3 2 4
输出样例
2
2
3
0
数据范围
20%数据满足:1≤n≤1000,1≤m≤10000;
40%数据满足:1≤n≤10000,1≤m≤100000;
100%数据满足:1≤n≤1000000,1≤m≤10000000;1≤m*p+q,m*q+p≤231-1;
=======================================
开始再为会爆栈而烦恼..在网上找到了个不用栈实现并查集的方法
ORZ...
=================================
var
n,m,p,q:longint;
color:array[1..1000000]of longint;
fa:array[0..1000000]of longint;
sum:array[0..1000000]of longint;
procedure init;
begin
assign(input,'paint.in');
assign(output,'paint.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function min(a,b:longint):longint;
begin
if a>b then exit(b);
exit(a);
end;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
function find(x:longint):longint;
var c1,c2:longint;
begin
c1:=x;
while c1<>fa[c1] do c1:=fa[c1];
while x<>fa[x] do begin
c2:=fa[x];
fa[x]:=c1;
x:=c2;
end;
exit(c1);
end;
procedure main;
var
i,j:longint;
l,r:longint;
tem:longint;
c:longint;
begin
readln(n,m,p,q);
fillchar(color,sizeof(color),0);
for i:=0 to n do fa[i]:=i;
//赋初始值
c:=1;
if m>n then c:=m-n+c;
for i:=m downto c do
begin
l:=(i*p+q)mod n+1;
r:=(i*q+p)mod n+1;
if l>r then begin tem:=l; l:=r; r:=tem; end;
r:=find(r);
while (l<=r) do
begin
if color[r]=0 then begin color[r]:=i; fa[r]:=find(fa[r-1]); r:=fa[r-1]; end
else begin fa[r]:=find(fa[r-1]); r:=fa[r-1]; end;
end;
end;
for i:=1 to n do writeln(color[i]);
end;
begin
init;
main;
terminate;
end.