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 4

Sample Output

6

HINT

说明:第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物品调度(双向链表+并查集+置换)的更多相关文章

  1. BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换

    BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置 ...

  2. 【BZOJ 1998】[Hnoi2010]Fsk物品调度 置换群+并查集

    置换群的部分水得一比,据说是经典的置换群理论(然而我并不知道这理论是啥).重点就在于怎么求pos!!!容易发现这个东西是这样的:每次寻找pos,先在本环里找,找不到再往下一个环里找,直到找到为止……一 ...

  3. BZOJ 1998: [Hnoi2010]Fsk物品调度 [置换群 并查集]

    传送门 流水线上有n个位置,从0到n-1依次编号,一开始0号位置空,其它的位置i上有编号为i的盒子.Lostmonkey要按照以下规则重新排列这些盒子. 规则由5个数描述,q,p,m,d,s,s表示空 ...

  4. [BZOJ1998][Hnoi2010]Fsk物品调度

    [BZOJ1998][Hnoi2010]Fsk物品调度 试题描述 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置,从0到n-1依次编号,一开 ...

  5. 【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)

    [BZOJ1998][HNOI2010]物品调度(并查集,模拟) 题面 BZOJ,为啥这题都是权限题啊? 洛谷 题解 先不管\(0\)位置是个空,把它也看成一个箱子.那么最终的答案显然和置换循环节的个 ...

  6. 【BZOJ】1998: [Hnoi2010]Fsk物品调度

    http://www.lydsy.com/JudgeOnline/problem.php?id=1998 题意: 给你6个整数$n,s,q,p,m,d$. 有$n$个位置和$n-1$个盒子,位置编号从 ...

  7. HNOI 2010 物品调度 并查集 置换

    题意: 题意有点细,暂不概括.请仔细审题. 分析: 我们先要把c生成出来. 记得颜神讲这道题,首先表明,这道题有两个问题需要处理. 第一个是要先定位,第二个是要求最小移动步数. 定位时对于每一个物品i ...

  8. 【BZOJ】1202: [HNOI2005]狡猾的商人(并查集+前缀和)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1202 用并查集+前缀和. 前缀和从后向前维护和,并查集从前往后合并 对于询问l, r 如果l-1和r ...

  9. 【BZOJ】1016: [JSOI2008]最小生成树计数 深搜+并查集

    最小生成树计数 Description 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不同的最小生成树.(如果两颗最小生成树中至少有一条边不同,则这两个最小 ...

随机推荐

  1. SpringBoot jar包不支持jsp

    官方原文如下: When running a Spring Boot application that uses an embedded servlet container (and is packa ...

  2. 【BZOJ4720】【NOIP2016】换教室 [期望DP]

    换教室 Time Limit: 20 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description Input 第一行四个整数n,m,v ...

  3. 【Codeforces】868C. Qualification Rounds

    [题目]C. Qualification Rounds [题意]给定n个问题和K个人,给定每个人知道的问题列表,求能否找到一个非空问题集合,满足每个人知道的集合中问题数量都不超过集合总题数的一半.n& ...

  4. Lua中调用C++方法

    目前项目,使用了Lua脚本,至于使用Lua的好处不再赘述了.于是对Tolua做了一些小小的学习,总结一下吧. 主要说一下如何在Lua中调用C++方法. Lua调用C++的桥梁,是tolua.tolua ...

  5. CSS(Cascading Style Shee)

    1.CSS是Cascading Style Sheet这个几个英文单词的缩写,翻译成中文是“层叠样式表”的意思 CSS能让网页制作者有效的定制.改善网页的效果. CSS是对HTML的补充,网页设计师曾 ...

  6. bzoj 1052 dfs

    首先可以二分答案,将最优性问题转化为判定性问题. 对于二分到的边长,我们可以把所有的点看成一个大的矩形,这个矩形为包括所有点的最小矩形,那么贪心的想,3个正方形,第一个肯定放在这个矩形其中的一角,然后 ...

  7. linux 下 /bin /sbin 的区别 -- (转)

    /bin,/sbin,/usr/bin,/usr/sbin区别 /  : this is root directory                root 用户根目录 /bin : command ...

  8. 转 TCP中的序号和确认号

    在网络分析中,读懂TCP序列号和确认号在的变化趋势,可以帮助我们学习TCP协议以及排查通讯故障,如通过查看序列号和确认号可以确定数据传输是否乱 序.但我在查阅了当前很多资料后发现,它们大多只简单介绍了 ...

  9. 如何用CMD开启3389与查看3389端口

    开启 REG ADD HKLM\SYSTEM\CurrentControlSet\Control\Terminal" "Server /v fDenyTSConnections / ...

  10. 【Matlab】使用Matlab运行Windows命令

    可以使用Matlab的一些命令来帮助程序运行.比如说 ! calc % 打开计算器 ! mspaint % 打开画图 dos calc % 打开计算器 比如一个程序要运行很长时间,而我们又不能一直守在 ...