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. 【bzoj3362-导航难题】带权并查集

    题意: 约翰所在的乡村可以看做一个二维平面,其中有N 座牧场,每座牧场都有自己的坐标,编号为1到N.牧场间存在一些道路,每条道路道路连接两个不同的牧场,方向必定平行于X 轴或Y轴.连通两座牧场之间的路 ...

  2. 省队集训 Day7 选点游戏

    [题目大意] 维护一个$n$个点的图,$m$个操作,支持两个操作: 1. 连接$(u, v)$这条边: 2. 询问$u$所在的联通块中,能选出的最大合法的点数. 一个方案是合法的,当且仅当对于所有被选 ...

  3. python进行机器学习(一)之数据预处理

    一.加载数据 houseprice=pd.read_csv('../input/train.csv') #加载后放入dataframe里 all_data=pd.read_csv('a.csv', h ...

  4. TCP之Nagle算法与延迟ACK

    (一)Nagle算法 为了减少网络中小分组的数目,减少网络拥塞的情况.Nagle算法要求在一条TCP连接上最多只能有一个未被确认的未完成小分组,在该分组ACK到达之前不能够发送其他的小分组,发送端需要 ...

  5. linux-open-source-development-tools【重点】

    https://www.pluralsight.com/blog/software-development/linux-open-source-development-tools https://ww ...

  6. visual studio 个性化设置

    尼马visual studio 的注释建设的真垃圾 Ctrl+K+C Ctrl+K+U, 通过工具->选项->环境->键盘->命令包含中搜索“注释选定内容”,分配成 Ctrl+ ...

  7. [New learn]响应者链机制介绍

    1.简介  测试代码库:https://github.com/xufeng79x/EventHandler 响应者链是系统寻找事件相应者的一个路径,他是同touch事件的Hit-testing过程具有 ...

  8. jQuery通过Ajax向PHP服务端发送请求并返回JSON数据

    SON(JavaScript Object Notation) 是一种轻量级的数据交换格式.易于人阅读和编写,同时也易于机器解析和生成.JSON在前后台交互的过程中发挥着相当出色的作用.请接着往下看教 ...

  9. WdatePicker做出onchange效果

    WdatePicker({onpicking: function (dp) {if (dp.cal.getDateStr() != dp.cal.getNewDateStr()) { Func(dp. ...

  10. Mac 使用自带的Ruby 安装brew

    Homebrew简称brew,OSX上的软件包管理工具,在Mac终端可以通过brew安装.更新.卸载软件. 首先要安装brew,在 mac 中使用finder 搜索 终端(terminal)打开命令行 ...