【BZOJ 1998】 1998: [Hnoi2010]Fsk物品调度(双向链表+并查集+置换)
1998: [Hnoi2010]Fsk物品调度
Description
现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位。流水线上有n个位置,从0到n-1依次编号,一开始0号位置空,其它的位置i上有编号为i的盒子。Lostmonkey要按照以下规则重新排列这些盒子。 规则由5个数描述,q,p,m,d,s,s表示空位的最终位置。首先生成一个序列c,c0=0,ci+1=(ci*q+p) mod m。接下来从第一个盒子开始依次生成每个盒子的最终位置posi,posi=(ci+d*xi+yi) mod n,xi,yi是为了让第i个盒子不与之前的盒子位置相同的由你设定的非负整数,且posi还不能为s。如果有多个xi,yi满足要求,你需要选择yi最小的,当yi相同时选择xi最小的。 这样你得到了所有盒子的最终位置,现在你每次可以把某个盒子移动到空位上,移动后原盒子所在的位置成为空位。请问把所有的盒子移动到目的位置所需的最少步数。Input
第一行包含一个整数t,表示数据组数。接下来t行,每行6个数,n,s,q,p,m,d意义如上所述。 对于30%的数据n<=100,对于100%的数据t<=20,n<=100000,s<n。其余所有数字均为不超过100000的正整数。 <="" div="">Output
对于每组数据输出一个数占一行,表示最少移动步数。Sample Input
1
8 3 5 2 7 4Sample Output
6HINT
说明:第1个到第7个盒子的最终位置依次是:2 5 6 4 1 0 7
计算过程可能超过整型范围。Source
【分析】
啊,我好笨。
先看那两个公式。
ci+1=(ci*q+p) mod m
posi=(ci+d*xi+yi) mod n
观察题目就知道主要是求pos数组,后面的就是置换的很基本的东西,弄成循环就好了。
pos数组怎么求呢,当然暴力是会超时的。
观察一下他的形式,发现如果yi也固定,那么走的是一个环。
如果这个环里面所有元素都被取走了,那么就跳到下一个环,直到环里面有东西为止。
就是模拟一个这样的过程,然后当然虽说是跳直到找到有环,但当然还是不能这样做的,所以我用了并查集和双向链表搞这个东西。
环的数量是gcd(n,d)【表示我一开始还搞错这个很久
求出pos数组之后,把置换分成互不相交的循环
若循环长度>1,且空格在里面,则ans+=L-1
否则ans+=L+1
【最后那部分还是很简单的】
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Maxn 1000010
#define INF 0xfffffff
#define LL long long int n,s,m,d;
int nt[Maxn],lt[Maxn],fa[Maxn];//环
int ntt[Maxn],ltt[Maxn],fax[Maxn];//环集
int pos[Maxn],id[Maxn];
LL c[Maxn],q,p; int ffa(int x)
{
if(fa[x]!=x) fa[x]=ffa(fa[x]);
return fa[x];
} int ffax(int x)
{
if(fax[x]!=x) fax[x]=ffax(fax[x]);
return fax[x];
} int gcd(int a,int b)
{
if(b==) return a;
return gcd(b,a%b);
} bool vis[Maxn]; int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int L;
scanf("%d%d%lld%lld%d%d",&n,&s,&q,&p,&m,&d);
d%=n;
for(int i=;i<n;i++) nt[i]=(i+d)%n;
for(int i=;i<n;i++) lt[i]=(i-d+n)%n;
c[]=;
for(int i=;i<n;i++) c[i]=(c[i-]*q+p)%m;
for(int i=;i<n;i++) fa[i]=i;
for(int i=;i<n;i++) c[i]%=n;
if(d!=) L=gcd(n,d);
else L=n;
for(int i=;i<L;i++) fax[i]=i;
for(int i=;i<L;i++)
{
id[i]=i;
int x=nt[i];
while(x!=i)
{
id[x]=i;
x=nt[x];
}
} memset(vis,,sizeof(vis));
for(int i=;i<n;i++)
{
int nw=ffax(id[c[i]]); pos[i]=ffa((c[i]+(nw-id[c[i]]+L)%L)%n); if(i==) pos[i]=s,nw=s%L;
if(lt[pos[i]]==pos[i])
{
fax[nw]=(nw+)%L;
}
else
{
nt[lt[pos[i]]]=nt[pos[i]];
lt[nt[pos[i]]]=lt[pos[i]];
fa[pos[i]]=nt[pos[i]];
}
}
LL ans=;
memset(vis,,sizeof(vis));
for(int i=;i<n;i++) if(vis[i]==)
{
int x=i,cnt=;
bool p=;
while(vis[x]==)
{
cnt++;
if(x==s) p=;
vis[x]=;
x=pos[x];
}
if(cnt>)
{
if(p) ans+=cnt-;
else ans+=cnt+;
}
}
printf("%d\n",ans);
}
return ;
}
2017-01-13 09:30:25
【BZOJ 1998】 1998: [Hnoi2010]Fsk物品调度(双向链表+并查集+置换)的更多相关文章
- BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换
BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置 ...
- 【BZOJ 1998】[Hnoi2010]Fsk物品调度 置换群+并查集
置换群的部分水得一比,据说是经典的置换群理论(然而我并不知道这理论是啥).重点就在于怎么求pos!!!容易发现这个东西是这样的:每次寻找pos,先在本环里找,找不到再往下一个环里找,直到找到为止……一 ...
- BZOJ 1998: [Hnoi2010]Fsk物品调度 [置换群 并查集]
传送门 流水线上有n个位置,从0到n-1依次编号,一开始0号位置空,其它的位置i上有编号为i的盒子.Lostmonkey要按照以下规则重新排列这些盒子. 规则由5个数描述,q,p,m,d,s,s表示空 ...
- [BZOJ1998][Hnoi2010]Fsk物品调度
[BZOJ1998][Hnoi2010]Fsk物品调度 试题描述 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置,从0到n-1依次编号,一开 ...
- 【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)
[BZOJ1998][HNOI2010]物品调度(并查集,模拟) 题面 BZOJ,为啥这题都是权限题啊? 洛谷 题解 先不管\(0\)位置是个空,把它也看成一个箱子.那么最终的答案显然和置换循环节的个 ...
- 【BZOJ】1998: [Hnoi2010]Fsk物品调度
http://www.lydsy.com/JudgeOnline/problem.php?id=1998 题意: 给你6个整数$n,s,q,p,m,d$. 有$n$个位置和$n-1$个盒子,位置编号从 ...
- HNOI 2010 物品调度 并查集 置换
题意: 题意有点细,暂不概括.请仔细审题. 分析: 我们先要把c生成出来. 记得颜神讲这道题,首先表明,这道题有两个问题需要处理. 第一个是要先定位,第二个是要求最小移动步数. 定位时对于每一个物品i ...
- 【BZOJ】1202: [HNOI2005]狡猾的商人(并查集+前缀和)
http://www.lydsy.com/JudgeOnline/problem.php?id=1202 用并查集+前缀和. 前缀和从后向前维护和,并查集从前往后合并 对于询问l, r 如果l-1和r ...
- 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集
最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...
随机推荐
- [cerc2012][Gym100624B]20181013
- 「6月雅礼集训 2017 Day7」电报
[题目大意] 有n个岛屿,第i个岛屿有有向发射站到第$p_i$个岛屿,改变到任意其他岛屿需要花费$c_i$的代价,求使得所有岛屿直接或间接联通的最小代价. $1 \leq n \leq 10^5, 1 ...
- 【BZOJ】1188 [HNOI2007]分裂游戏
[算法]博弈论 [题解] 我们的目的是把游戏拆分成互不影响的子游戏,考虑游戏内的转移. 如果把每堆视为子游戏,游戏之间会相互影响,不成立. 将每堆的一个石子视为子游戏,其产生的石子都在同一个子游戏中. ...
- 【BZOJ】2502 清理雪道
[算法]有源汇上下界最小流 [题解]上下界 初看以为是最小覆盖,发现边可以重复经过,不对. 要求所有边都经过……那就下界为1,上界为inf的可行流. 源汇……S连入度为0的点,T连出度为0的点?(反正 ...
- 苹果API常用英语名词---iOS-Apple苹果官方文档翻译
本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址 苹果API常用英语名词0. indicating 决定1.in order to 以便 ...
- bzoj 1093 缩点+DP
首先比较明显的是如果存在一个半连通子图,我们将其中的环缩成点,那么该图仍为半连通子图,这样我们就可以先将整张图缩点,重新构图,新图为拓扑图,记录每个新的点表示的强连通分量中点的个数num[i],那么我 ...
- 移动端 H5 页面注意事项
1. 单个页面内容不能过多 设计常用尺寸:750 x 1334 / 640 x 1134,包含了手机顶部信号栏的高度. 移动端H5活动页面常常需要能够分享到各种社交App中,常用的有 微信.QQ 等. ...
- Perl6 Bailador框架(7):模版编写
先看一个例子: use v6; use Bailador; my $data = ' <form action="", method="get"> ...
- 简谈const限定符
const修饰的数据类型是常量类型,常量类型的对象和变量在定义初始化后是不能被更新的.其实只用记住这一个概念,就可以明白const操作对象的方法. 1)定义const常量 最简单的: const in ...
- Python基础=== Tkinter Grid布局管理器详解
本文转自:https://www.cnblogs.com/ruo-li-suo-yi/p/7425307.html @ 箬笠蓑衣 Grid(网格)布局管理器会将控件放置到一个二维的表 ...