题意:给定一个序列,多次将某个区间染成某种颜色,求最后每个点是什么颜色
由于只求最后染的颜色,所以倒着染
这样一个位置最多只需要染一次,染过就不需要再染
也就是说,对于当前染色,区间内已经染色的位置这次染色就要直接跳过,即只染区间内还没有被染色的
并查集的一个经典神助攻:删除一个数后快速找到它后面第一个没有删除的数(处理完一个位置后快速找打它后面第一个需要处理的位置)
这样就能保证每个位置只被染一次
时间复杂度O(n+m)
这个神助攻经常被用来“每个位置最多只会被处理一次”和“标记”和“快速找到最近的满足条件的位置”,常和离线、预处理、“正难则反”等结合,非常腻害
{$M 100000000}
var
n,m,p,q,l,r,c :longint;
father,a :array[0..1000010] of longint;
i :longint;
function get_father(x:longint):longint;
begin
if x=father[x] then exit(x);
father[x]:=get_father(father[x]);
exit(father[x]);
end;
begin
read(n,m,p,q);
for i:=1 to n+1 do father[i]:=i;
for i:=m downto 1 do
begin
l:=(i*p+q) mod n+1;
r:=(i*q+p) mod n+1;
if l>r then
begin
c:=l; l:=r; r:=c;
end;
l:=get_father(l);
while l<=r do
begin
a[l]:=i;
father[l]:=get_father(l+1);
l:=get_father(l+1);
end;
end;
for i:=1 to n do writeln(a[i]);
end.
——by Eirlys