【并查集】疯狂的涂色
来源:互联网 发布:农村淘宝现状分析 编辑:程序博客网 时间:2024/05/16 10:16
疯狂的涂色
小t非常喜爱画画,但是他还是一个初学者。他最近费尽千辛万苦才拜到小Q为师。小Q是画鸡蛋长大的,让小t一入门就拿着一张白纸条疯狂地涂色。假设纸条被划分成了n个区域,用1~n的整数从左到右顺序编号,小Q总共下达了m条指令。第i条指令是让小t把编号为(i*p+q)modn+1与(i*q+p)mod n+1(p,q为常整数)之间的区域(连续的一段区域)涂成第i种颜色。
现在由于小Q下达的指令过多,小t一时应付不过来。小Q只让他回答每一个区域最后的颜色。趁小Q还在“五谷轮回之所”忙碌时,小t偷偷的请让你这个计算机高手帮他算出最后的颜色状态,并告诉他。
输入格式
文件仅一行,为四个整数n,m,p,q。
输出格式
文件共n行,第i行代表最后第i个格子的颜色。白色编号为0。
输入样例
4 32 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;
这道题中,左右界周期性,所以需要找循环节,可以降低时间复杂度。。。这个最恼人了,到现在还没有掌握,虽然打出来了。
这道题真的有点难。除了考虑循环节之外,还要考虑一个尽量不重复刷。
因此本题正解是,从最后一刷往前枚举。因为只需要知道最后颜色状态,因此只需要刷最后一段,上一个周期重复的就不再刷。
倒着刷,就保证了先刷的是要保留的,因此后面遇到就不能再刷了,这个用一个并查集来维护,跟前段时间覃禹舜讲的一道题很相似,
也是用并查集维护下一个需要处理的点,(这种特殊的并查集必须要让旧点的父亲指向新点)。
另外这道题有点变态的地方,如果写普通的并查集要栈溢出,深度过大。因此要写一个手工的栈,模拟递归。。。
long t;
while (fa[a]!=a)
{
stack[++top] = a;
a=fa[a];
}
t = fa[a];
这部分递归求根,
while (top>0)
{
a = stack[top];
top--;
fa[a] = t;
}
return t;
这部分回溯压缩树的深度。
//#include <iostream>//using std::cout;//using std::cin;#include <cstdio>const long oo = 0x7fff0000;long c[1000002];long fa[1000002];long stack[1000002];long top = 0;long n;long m;long p;long q;long getroot(long a){long t;while (fa[a]!=a){stack[++top] = a;a=fa[a];}t = fa[a];while (top>0){a = stack[top];top--;fa[a] = t;}return t;}int main(){freopen("paint.in","r",stdin);freopen("paint.out","w",stdout);scanf("%ld%ld%ld%ld",&n,&m,&p,&q);long lm;long rm;for (long i=1;i<n+1;i++){fa[i] = i;}for (long i=m;i>0&&m-i+1<=n;i--){long l = (i*p+q)%n +1;long r = (i*q+p)%n +1;if (l>r){long tmp=l;l=r;r=tmp;}if(i==m){lm=(m*p+q)%n+1;rm=(m*q+p)%n+1;}else if(l==lm&&r==rm)break;for (long j=getroot(r);j>l-1;j=getroot(j)){if (c[j]==0)c[j] = i;fa[j] = j-1;}}for (long i=1;i<n+1;i++){printf("%ld\n",c[i]);}return 0;}
- 【并查集】疯狂的涂色
- 【并查集思想的应用.】疯狂的涂色
- 【BZOJ2054】疯狂的馒头【BZOJ2375】疯狂的涂色【并查集】
- HDU 4056 涂色 并查集
- 【bzoj2054】 疯狂的馒头 并查集
- 【bzoj2054】【疯狂的馒头】【并查集】
- BZOJ2054 疯狂的馒头 并查集
- bzoj 2375: 疯狂的涂色
- BZOJ 2054 疯狂的馒头 并查集
- 【BZOJ 2054】疯狂的馒头 并查集
- bzoj 2054: 疯狂的馒头 并查集
- BZOJ 2054: 疯狂的馒头 并查集题解
- 【BZOJ2054】疯狂的馒头(并查集)
- #BZOJ2054#疯狂的馒头(并查集经典)
- [BZOJ2054] 疯狂的馒头/[BZOJ2375] 疯狂的涂色
- 并查集的实现
- 并查集的使用
- 并查集的学习
- utc
- 链表
- 一段Parsec CSV文件的haskell代码
- JAVA中的堆和栈
- 简单标签
- 【并查集】疯狂的涂色
- C++的cout与cerr的区别
- 多态就是变态
- 二叉树
- 学习易语言之用力点
- Linux设备模型<三>总线、设备、驱动程序
- 这段代码处理排版比较乱的文本文件,但是我一直整理文件不成功,忘记从哪个大牛的网站上摘来的,抱歉!
- 国内移动应用使用量飙升 移动互联网渐成消费金矿
- 区分Activity的四种加载模式