[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自己单独一个循环节的情况

可是感觉这样的时间复杂度不是很科学,并查集的过程最坏O(n2)?但是貌似很难卡…

代码

#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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 电大英语考试成绩取消了怎么办 网贷评分不足要怎么办 学业水平广东1c怎么办 绣花机速度太慢怎么办 娃脖子有点烂了怎么办 7月省内流量套餐怎么办 qq手游授权失败怎么办 钉钉不够6人创建怎么办 钉钉 不够6个人怎么办 plsql删错了表怎么办 吊兰长出来的茎怎么办 防水台鞋跟太高怎么办 证件照头部比例过大怎么办 特岗照片传错了怎么办 打印报名表照片不显示怎么办 刚买的床有味道怎么办 雨刷器角度太小怎么办 四个月宝宝闹觉怎么办 怀孕六个月睡不好觉怎么办? 婴儿睡不好觉总是吵闹怎么办 婴儿鼻塞睡不好觉怎么办 玩英雄联盟鼠标变亮白怎么办 练芭蕾脚受伤了怎么办 高三了英语30分怎么办 要上高中了英语不好怎么办 高二了数学不好怎么办 高二函数不好怎么办啊 输乳怎么办腺病有什么妇症状 屁股上坐的发黑怎么办 车屁股撞了个洞怎么办 腰压迫的腿疼怎么办 肩胛提肌固定不住怎么办 胳膊粗后背肉多怎么办 2岁儿童 肋骨边缘外翻怎么办 5岁宝宝盆骨前倾怎么办 脖子弯了像驼背怎么办 都40周了还没生怎么办 股骨头坏死骨盆歪了怎么办 二胎侧切伤口疼怎么办 小月子盆骨酸痛怎么办 盆骨一边大一边小怎么办