[BZOJ1998][Hnoi2010]Fsk物品调度(置换群+并查集)
来源:互联网 发布:小企业会计记账软件 编辑:程序博客网 时间:2024/06/06 18:38
题目描述
传送门
题解
首先考虑如何构造出pos
因为要求在x最小的情况下y最小
那么当y固定的时候x会有一坨取值,也会有一些不同的数
考虑先枚举y=0,然后如果x没有合适的取值再将y+1
因为要求最终的答案不重复,那么如果w已经在答案中出现过了,那么w+d是有可能出现的(将x+1),所以用并查集将w并到w+d
这样的话,首先枚举y,如果ci+y所在的集合中的元素都被选过了,那么只能将y+1
求出pos之后,考虑如何求答案
这就是一个置换,存在若干个循环节。循环节长度为1的不用管,考虑长度大于1的。如果某一个大小为k循环节中有0(有空位),那么可以直接交换k-1次将这个循环节归位;如果某一个大小为k的循环节中没有0,那么先将0强拉进来,然后用k-1次归位,再将0放回去,这样是k+1次
找出来所有的循环节就可以了
注意要是直接计数的话要考虑0自己单独一个循环节的情况
可是感觉这样的时间复杂度不是很科学,并查集的过程最坏
代码
#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define LL long long#define N 100005int T,n,q,p,m,d,s,now,cnt,tot,ans;int c[N],pos[N],f[N];bool flag[N];void clear(){ n=q=p=m=d=s=now=cnt=tot=ans=0; memset(c,0,sizeof(c)); memset(pos,0,sizeof(pos)); memset(f,0,sizeof(f)); memset(flag,0,sizeof(flag));}int find(int x){ if (x==f[x]) return x; f[x]=find(f[x]); return f[x];}void merge(int x,int y){ int fx=find(x),fy=find(y); if (fx!=fy) f[fx]=fy;}int main(){ scanf("%d",&T); while (T--) { clear(); scanf("%d%d%d%d%d%d",&n,&s,&q,&p,&m,&d); c[0]=0; for (int i=1;i<n;++i) c[i]=((LL)c[i-1]*q%m+p)%m; for (int i=0;i<n;++i) f[i]=i; pos[0]=s;flag[s]=1;merge(s,(s+d)%n); for (int i=1;i<n;++i) { now=0; int x=find((c[i]+now)%n); while (flag[x]) { ++now; x=find((c[i]+now)%n); } pos[i]=x; flag[x]=1; merge(x,(x+d)%n); } memset(flag,0,sizeof(flag)); tot=0;ans=0; for (int i=0;i<n;++i) if (!flag[i]) { cnt=0; int x=i; while (!flag[x]) { ++cnt;flag[x]=1; x=pos[x]; } if (cnt>1) ans+=cnt,++tot; } if (!pos[0]) ans+=tot; else ans=(ans-1)+tot-1; printf("%d\n",ans); }}
0 0
- [BZOJ1998][Hnoi2010]Fsk物品调度(置换群+并查集)
- 【bzoj1998】Fsk物品调度 置换群+并查集
- bzoj1998[Hnoi2010] Fsk物品调度
- bzoj 1998: [Hnoi2010]Fsk物品调度 (置换+并查集)
- 1998: Fsk物品调度 并查集
- [BZOJ 1998][Hnoi2010]Fsk物品调度
- BZOJ 1998: [Hnoi2010]Fsk物品调度
- BZOJ1997: [Hnoi2010]Planar(并查集)
- [BZOJ1997][Hnoi2010]Planar && 并查集
- 并查集(集并查)
- 页面置换、作业调度、进程调度(转)
- FSK
- NYOJ1249_物品调度
- 并查集(含关系并查集)
- 【并查集】食物链(关系并查集)
- 【并查集】并查集详解(转)
- 分组并查集(种类并查集)
- 并查集, 畅通工程(简单并查集)
- 类与类之间的几种关系
- MapReduce的Shuffle过程介绍
- angularjs2--tab页调用父页面的方法
- python最简单的爬虫
- 插入排序
- [BZOJ1998][Hnoi2010]Fsk物品调度(置换群+并查集)
- Node.js request实现技术灌水
- 链表判环练习
- 全排列计算(康托展开)
- JSON简单介绍
- 喝汽水问题
- android recent key长按事件弹起触发最近列表故障分析
- 在SpringBoot中使用 拦截器
- 浏览器兼容问题及解决办法