P5944 题解
Update:更正代码,修复几个锅。
知道每个人是第几个出圈的作用不大,不如转化为出圈序列。
不难发现,假如当前圈内剩余人数为
不难发现
问题等价于解同余方程组
直接 excrt 即可,无解即某次合并时无解。
需要注意的是最后可能会合并出
#include<cstdio>
int cq[31];
int n,ys[31],ms[31];
bool td[31];
long long gcd(long long x,long long y){
return x%y==0?y:gcd(y,x%y);
}
void exgcd(long long a,long long b,long long &x,long long &y){
if(!b){
x=1;y=0;
return;
}
exgcd(b,a%b,x,y);
long long z=x;
x=y;
y=z-a/b*y;
}
int main(){
int i;
scanf("%d",&n);
int p=0,x;
for(i=1;i<=n;i++){
scanf("%d",&x);
cq[x]=i;
}//cq 存储出圈序列
for(i=1;i<=n;i++){
int ds=0;
x=cq[i];
while(p!=x){
p++;if(p>n)p=1;
if(!td[p])ds++;
}
ms[i]=n-i+1;
ys[i]=ds%ms[i];
td[x]=1;
}
long long res=ys[1],mod=ms[1];//excrt 流程
for(i=2;i<=n;i++){
long long a=mod,b=ms[i],t=((ys[i]-res)%b+b)%b;
long long x,y,r=gcd(a,b);
if(t%r)return printf("NIE"),0;
a/=r;b/=r;t/=r;
exgcd(a,b,x,y);
x=x%ms[i]*t%ms[i];
res+=x*mod;
mod*=b;
res=(res+mod)%mod;
}
if(!res)res+=mod;
printf("%lld",res);
}