「HNOI2010」物品调度 题解

我们发现对于每一个数 p 总会有一个数 \(x \le n\) 使得 \(p\equiv p+x\times d(\mod n)\)

$ \therefore n| x\times d,x=\gcd(n,d)$

当然这个东西对做题的帮助不大,只是告诉我们这个数量是有限的。

那我们就可以把题目看做有很多个环,他们之间互相连边连成了一个大环,对于每一个小环,我们可以用一个并查集来维护,而总的大环,我们亦可以用并查集来维护,对于每一个初始点 \(c_i\),我们可以先找到这个点的最近的没有被全覆盖的小环,在算出到这个小环是的数字是多少,对于这个数字,找到这个数字的下一个在环内的没有被覆盖的数字(不能是 \(s\))。对于最少步数很简单,可以类似模拟的做。

坑点:\(c_i\) 可能大于 \(n\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1E5+5;
int T;
int n,s,q,p,m,d;
int c[N];
int mark[N];
int pos[N],sz[N],nxt[N],fa[N],vis[N],bel[N];
int find1(int x) {
	return sz[x]?x:nxt[x]=find1(nxt[x]);
}
int find2(int x){
	return (!vis[x] && x!=s)?x:fa[x]=find2(fa[x]); 
}
int ans,tot;
signed main() {
	scanf("%lld",&T);
	while(T--) {
		ans=tot=0;
		memset(mark,0,sizeof mark);
		memset(vis,0,sizeof vis);
		memset(sz,0,sizeof sz);
		memset(fa,0,sizeof fa);
		memset(nxt,0,sizeof nxt);
		memset(bel,0,sizeof bel);
		memset(pos,0,sizeof pos);
		scanf("%lld%lld%lld%lld%lld%lld",&n,&s,&q,&p,&m,&d);
		for(int i=1; i<n; i++)
			c[i]=(c[i-1]*q+p)%m;
		
		for(int i=0; i<n; i++) {
			if(mark[i])continue;
			int j=i;
			while(!mark[j]) {
				mark[j]=1;
				sz[i]++;
				bel[j]=i;
				if(j==s)sz[i]--;
				fa[j]=(j+d)%n;
				j=(j+d)%n;
			}++tot;
		}
		
		for(int i=0; i<tot; i++)
			nxt[i]=i+1;
		nxt[tot-1]=0;//记录下一个有空的环
		for(int i=1; i<n; i++) {
			int p=find1(bel[c[i]%n]);
			sz[p]--;
			int y=(p-bel[c[i]%n]);
			if(y<0)y+=tot;
			//求出最近的空的环
			pos[i]=find2((c[i]+y)%n);
			vis[pos[i]]=1;
		}
		pos[0]=s;
		memset(vis,0,sizeof vis);
		for(int i=0;i<n;i++){
            if(!vis[i]){
                vis[i]=1;
				int now=i;
                int cnt=1,flag=now==s;
                while(!vis[pos[now]]){
                    now=pos[now];vis[now]=1;
                    cnt++;
					if(now==s) flag=1;
                }
                if(flag) ans+=cnt-1;
                else if(cnt>1) ans+=cnt+1;
            }
        } 
        cout<<ans<<endl;
		//个数 gcd(n,d)
		//长度 n/gcd(n,d)
		//可以证明若在枚举时这个数已经 mark 过了,之后的数也肯定全部被标记了
	}
	return 0;
}

posted @ 2025-03-21 14:07  hnczy  阅读(24)  评论(0)    收藏  举报