[HNOI2010] 物品调度 fsk
标签:链表+数论知识。
题解:
对于这道题,其实就是两个问题的拼凑,我们分开来看。
首先要求xi与yi。这个可以发现,x每增加1,则pos增加d;y每增加1,则pos增加1。然后,我们把x与y分别写在二维平面上,比如样例:
x= 0 1
y=0 {0 4}
y=1 {1 5}
y=2 {2 6}
y=3 {3 7}
发现行数=gcd(n,d),列数=n/gcd(n,d)。
那么题目要求y尽量小,然后x尽量小。我们先求y,那么初始pos就是ci,把ci放入这张表,寻找最近的可以不重复的行,也就是y。找到之后我们再把ci+y代入,去找在第y行的哪一个数是最近的,这样就能找到x与y了。
具体的:我们使用rx[i],代表x=i时,右边那个可用的是哪一个,rx_cnt[i]代表距离。同样ry[i],与ry_cnt[i]分别表示y=i的下面的哪一个与距离。每次修改(也就是标记Val已经被使用)仅仅需要对于(Val+d)%n即可,然后rx[Val]=(Val+d)%n,rx_cnt[Val]=1。将Val%=gcd,即可完成对于y的修改。
修改那么简单,那么查询:类似并查集一样的进行路径压缩,即如果rx[Val]被使用,那么rx[Val]=find(rx[Val]),对应修改rx_cnt[Val]即可,然后返回rx_cnt[Val]为x的值,y同样如此。
解决了这个问题,下面求解最小步数就很简单了。我们在纸上将i与pos[i]连上一条边,发现会构成很多个环,如果这个环中有0,那么直接把0按照环的反方向依次移动,即可把整个环都归位,如果环中没有0,那么先把0移进去,归位之后再移出来,步数+2即可,这样是最优的方案。证明可以使用置换群什么的。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int MAXN=;
bool vis[MAXN];
int T,n,s,q,p,m,d,ans;
int c[MAXN],pos[MAXN],cnt[MAXN],rx[MAXN],ry[MAXN],rx_cnt[MAXN],ry_cnt[MAXN];
inline int gi(){int res; scanf("%d",&res); return res;}
int gcd(int A,int B)
{
if(A%B==)return B;
return gcd(B,A%B);
}
void insert(int x)
{
int tmp;
if((tmp=x+d)>=n)tmp-=n;
rx[x]=tmp;
rx_cnt[x]=;
x%=m;
if(--cnt[x])return;
if((tmp=x+)>=m)tmp-=m;
ry[x]=tmp;
ry_cnt[x]=;
}
int query(int *r,int *r_cnt,int x)
{
if(r[x]==x)return ;
r_cnt[x]=r_cnt[x] + query(r,r_cnt,r[x]);
r[x]=r[r[x]];
return r_cnt[x];
}
int main()
{
T=gi();
while(T--)
{
scanf("%d%d%d%d%d%d",&n,&s,&q,&p,&m,&d); pos[]=s;
for(int i=;i<n;i++) c[i]=((LL)c[i-]*q+p)%m;
d%=n;//insert()中没有使用取模,而是使用减法代替,所以这里先模一下。
m=gcd(n,d);
for(int i=;i<m;i++)
{
cnt[i]=n/m;
ry[i]=i;
ry_cnt[i]=;
}
for(int i=;i<n;i++) rx[i]=i,rx_cnt[i]=;
insert(pos[]);
for(int i=;i<n;i++)
{
int y=query(ry,ry_cnt,c[i]%m);
int x=query(rx,rx_cnt,(c[i]+y)%n);
pos[i]=((LL)d*x+y+c[i])%n;
insert(pos[i]);
}
ans=; memset(vis,,sizeof vis);
for(int i=;i<n;i++)
if(!vis[i])
{
int now=i,Start=i,flag=,cnt=;
do
{
vis[now]=; cnt++;
if(now==)flag=;
now=pos[now];
}while(now!=Start);
if(cnt>)
{
ans+=cnt-;
if(!flag)ans+=;
}
}
printf("%d\n",ans);
}
return ;
}
[HNOI2010] 物品调度 fsk的更多相关文章
- 【BZOJ1998】[HNOI2010]物品调度(并查集,模拟)
[BZOJ1998][HNOI2010]物品调度(并查集,模拟) 题面 BZOJ,为啥这题都是权限题啊? 洛谷 题解 先不管\(0\)位置是个空,把它也看成一个箱子.那么最终的答案显然和置换循环节的个 ...
- [HNOI2010]物品调度
题目描述 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置,从0到n-1依次编号,一开始0号位置空,其它的位置i上有编号为i的盒子.Lostm ...
- P3207 [HNOI2010]物品调度
传送门 完了题目看错了--还以为所有的\(x,y\)都要一样--结果题解都没看懂-- 先考虑如果已经求出了所有的\(pos\)要怎么办,那么我们可以把\(0\)也看做是一个箱子,然后最后每个箱子都在一 ...
- [BZOJ1998][Hnoi2010]Fsk物品调度
[BZOJ1998][Hnoi2010]Fsk物品调度 试题描述 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置,从0到n-1依次编号,一开 ...
- 【BZOJ 1998】 1998: [Hnoi2010]Fsk物品调度(双向链表+并查集+置换)
1998: [Hnoi2010]Fsk物品调度 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置,从0到n-1依次编号 ...
- BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换
BZOJ_1998_[Hnoi2010]Fsk物品调度_并查集+置换 Description 现在找工作不容易,Lostmonkey费了好大劲才得到fsk公司基层流水线操作员的职位.流水线上有n个位置 ...
- 【BZOJ】1998: [Hnoi2010]Fsk物品调度
http://www.lydsy.com/JudgeOnline/problem.php?id=1998 题意: 给你6个整数$n,s,q,p,m,d$. 有$n$个位置和$n-1$个盒子,位置编号从 ...
- BZOJ 1998: [Hnoi2010]Fsk物品调度 [置换群 并查集]
传送门 流水线上有n个位置,从0到n-1依次编号,一开始0号位置空,其它的位置i上有编号为i的盒子.Lostmonkey要按照以下规则重新排列这些盒子. 规则由5个数描述,q,p,m,d,s,s表示空 ...
- 【BZOJ 1998】[Hnoi2010]Fsk物品调度 置换群+并查集
置换群的部分水得一比,据说是经典的置换群理论(然而我并不知道这理论是啥).重点就在于怎么求pos!!!容易发现这个东西是这样的:每次寻找pos,先在本环里找,找不到再往下一个环里找,直到找到为止……一 ...
随机推荐
- NET 并发编程
场景并发调用API 1.简单封装httpclient public class CommonHelper { private static readonly HttpClient _httpClien ...
- 九度OJ 1115:数字求和 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2396 解决:1507 题目描述: 给定一个正整数a,以及另外的5个正整数,问题是:这5个整数中,小于a的整数的和是多少? 输入: 输入一行 ...
- Create a /etc/yum.repos.d/mongodb-org-4.0.repo
Install MongoDB Community Edition on Red Hat Enterprise or CentOS Linux — MongoDB Manual https://doc ...
- vmware虚拟机centos网络配置错误,执行/etc/init.d/network start 或 restart 提示Device eth0 has different MAC address than expected, ignoring
vmware虚拟机centos网络配置错误,执行/etc/init.d/network start 或 restart 提示Device eth0 has different MAC address ...
- [数据挖掘课程笔记]人工神经网络(ANN)
人工神经网络(Artificial Neural Networks)顾名思义,是模仿人大脑神经元结构的模型.上图是一个有隐含层的人工神经网络模型.X = (x1,x2,..,xm)是ANN的输入,也就 ...
- [CPP] Coding Style
C++ Coding Style C++很多强大的语言特性导致它的复杂,其复杂性会使得代码更容易出现bug.难于阅读和维护. 由于,本人有一点点代码洁癖,所以依照Google的C++编程规范<G ...
- 'gbk' codec can't encode character '\xa5' in position 4546: illegal multibyte sequence错误解决
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='gb18030') 原文 http://blog.csdn.net/jim7424 ...
- codeforces 463C. Gargari and Bishops 解题报告
题目链接:http://codeforces.com/contest/463/problem/C 题目意思:要在一个 n * n 大小的棋盘上放置两个bishop,bishop可以攻击的所有位置是包括 ...
- AutoIT:界面与自动化操作结合来简化日常劳动: .Net Reactor验证License,设置License,创建License,截图AutoIt自动化实现。(七)
版本六中存在一个显著问题是: 当exe文件生存之后,运行的时候,通过consoleWrite函数打印出来的数据是无法展示出来的.这就存在一个问题:当运行失败的时候,我还是看不到任何log信息. 于是, ...
- vs2012安装程序,无法注册ActiveX
最近开发环境换成了vs2012,用C#写了一个ActiveX插件程序,然后添加一个安装程序,但是安装后,ie无法识别AcitveX,在ie的Manage add-ons中也找不到,这在vs2010是没 ...