【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 ans[MaxN], flag[MaxN], fa[MaxN];
 9
10 int find(int x){
11     if (!fa[x]) return x;
12     return fa[x] = find(fa[x]);
13 }
14
15 int main(){
16     scanf("%d%d%d%d", &n, &m, &p, &q);
17     for (int i = m; i; i--){
18         int l = (int) ((LL) i * p + q) % n + 1;
19         int r = (int) ((LL) i * q + p) % n + 1;
20         if (l > r) swap(l, r);
21         for (int j = find(l); j <= r; j = find(j)){
22             ans[j] = i; fa[j] = j+1;
23         }
24     }
25     for (int i = 1; i <= n; i++) printf("%d\n", ans[i]);
26     return 0;
27 }
时间: 2024-10-12 14:45:11

【BZOJ2054】疯狂的馒头(并查集)的相关文章

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 疯狂的馒头

还是离线把操作倒过来做,于是每个馒头只要看最后一种颜色就好了 如果一个馒头已经有颜色了,就把它并到右边的馒头的集合里去 1 /************************************************************** 2 Problem: 2054 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:3268 ms 7 Memory:39776 kb 8 ***********************

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) 代码

交通灯 并查集

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>