BOZJ 2045:疯狂的馒头(并查集)

题目大意:有n个馒头排成一排,初始时颜色为0,进行m次染色,第i次将(i*p+q)mod n到(i*q+p)mod n的馒头全部染成颜色i,求最后所有馒头颜色。n<=10^6 m<=10^7

分析:nm很大不能线段树,可以考虑用并查集,我们发现每个馒头可能会被染色多次,但只有最后一次染色能决定它的最终颜色,故倒着做,并且使每个点颜色只修改一次,对于区间[x,y],从x开始将除以外的点父亲全部指向下一个,这样这个区间全部指向了y,下一次修改时会跳过该区间,由于只会修改n个点故效率为O(n)

代码:

program asfd;
var
  a:array[0..1000001]of longint;
  f:array[0..1000001]of longint;
  n,i,m,p,q,k,x,y,t,j:longint;
function find(x:longint):longint;
var i,j,k:longint;
begin
  i:=x; j:=x;
  while i<>f[i] do i:=f[i];
  while i<>j do
   begin
     k:=f[j]; f[j]:=i; j:=k;
   end;
  exit(i);
end;
begin
  readln(n,m,p,q);
  for i:=1 to n do f[i]:=i; k:=0;
  for i:=m downto 1 do
   begin
     x:=(i*p mod n+q)mod n+1;
     y:=(i*q mod n+p)mod n+1;
     if x>y then begin t:=x; x:=y; y:=t; end;
     j:=find(x);
     while j<=y do
      begin
        a[j]:=i; f[j]:=j+1; inc(k);
        if k=n then break;
        j:=find(j);
      end;
   end;
  for i:=1 to n do
   writeln(a[i]);
  readln;
end.

时间: 2024-12-06 18:46:25

BOZJ 2045:疯狂的馒头(并查集)的相关文章

Bzoj P2054 疯狂的馒头 | 并查集

题目链接 思路:因为每次染色都会将某些馒头的颜色彻底更改,所以每个馒头的最终的颜色其实是由最后一次染色决定的,那么我们只考虑最后一次染色即可.对此,我们可以从后往前倒着染色,当目前的染色区间中存在白色馒头时,就将其染成当前的颜色,对于已经染过色的馒头则不处理,因为当前这一次染色已经不是其最后一次染色了,其最终颜色已经确定了. 对以上思路,考虑用经过路径压缩优化的并查集来维护在每个馒头右侧的.距离最近的.未染色的馒头的位置,以减小时间复杂度. 总时间复杂度O(m+n). 代码: #include<

BZOJ 2054 疯狂的馒头 并查集

题目大意:给定一个序列,多次将某个区间染成某种颜色,求最后每个点是什么颜色 m<=1000W,线段树肯定T 由于对每个点起作用的染色只有最后一次,因此倒着做,如果一个点已经被染色,就在并查集中将这个点连向右面那个 这样每个点只会被染色一次,时间复杂度O(n+m) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 1001001

【BZOJ2054】疯狂的馒头(并查集)

链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2054 水题QAQ, 并查集就可以了. 1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #define LL long long 5 #define MaxN 1000010 6 using namespace std; 7 int n, m, q, p, S = 0; 8 int an

交通灯 并查集

Problem Description 相信交通灯对于你来说并不陌生,交通灯分为红色和绿色两个阶段,这两个阶段互相更替,保障着道路的安全. 在杭州一共有n个路口,编号依次为1到n.这些路口之间连接着m条双向道路,每条道路连接着两个不同的路口,且任意两个路口之间最多连接着一条道路.每条道路中央都设置着一个交通灯. 为了保障道路的安全,对于任意两条道路,如果它们连接了同一个路口,那么它们不能同色. 你的朋友正乘着飞机从杭州的上空飞过,并拍了一张杭州的照片.在照片里,每条道路的交通灯的颜色都清晰可辨.

CodeForces 745C Hongcow Builds A Nation 并查集

题意: 给了你n个城市 m条边 k个政府 每个政府管辖的区域内不能和其他政府的区域有相连 即政府之间不存在路径 问你在维护这种关系的同时 最多再加多少条边 思路: 先找出来每个联通块 再找出来没有归属的孤立的点 把他们都放到最大的联通块里 然后每个联通块之间的点两两连边是n*(n-1)/2条边 最后算出来的ans-m就好了 (看别人的博客学了一个max_element 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a

并查集(个人模版)

并查集: 1 int find(int a) 2 { 3 int r=a; 4 while(f[r]!=r) 5 r=f[r]; 6 int i=a; 7 int j; 8 while(i!=r) 9 { 10 j=f[i]; 11 f[i]=r; 12 i=j; 13 } 14 return r; 15 } 16 int merge(int a,int b) 17 { 18 int A,B; 19 A=find(a); 20 B=find(b); 21 if(A!=B) 22 { 23 f[B

并查集应用

题目描述: One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls

【bzoj3674】 可持久化并查集加强版

http://www.lydsy.com/JudgeOnline/problem.php?id=3674 (题目链接) 题意 维护并查集3个操作:合并:回到完成第k个操作后的状态:查询. Solution 其实就是用主席树的叶子节点维护并查集的可持久化数组fa[]. 细节 终于认识到了按秩合并的强大,单纯写个路径压缩Re飞,写了路径压缩+按秩合并比单纯的按秩合并每快多少→_→ 代码 // bzoj3674 #include<algorithm> #include<iostream>

BZOJ1015[JSOI2008]星球大战starwar[并查集]

1015: [JSOI2008]星球大战starwar Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 5253  Solved: 2395[Submit][Status][Discuss] Description 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道互相直接或间接地连接. 但好景不长,很快帝国又重