QAQ
总算自己做出来一个题。
第
i
轮有
那么就可以列出方程:
Ans≡r1 mod m1
Ans≡r2 mod m2
⋮ ⋮ ⋮
Ans≡rn−1 mod mn−1
最后一个没有用了,只用
n−1
个方程就行了。然后就是
ri
可能
=mi
,所以每一个
ri
要对
mi
求余。
然后用
ExCRT
合并。还有一点就是
Ans!=0
【代码】
#include <cstdio>
#include <iostream>
#include <algorithm>
#define N 25
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,M,R;
int a[N],pos[N],m[N],r[N];
void Exgcd(int a,int b,int &d,int &x,int &y)
{
if(b) {
Exgcd(b,a%b,d,y,x);
y-=(a/b)*x;
}
else x=1,y=0,d=a;
}
int Ex_CRT()
{
M=m[1],R=r[1];int x,y,d;
for(int i=2;i<n;i++)
{
Exgcd(M,m[i],d,x,y);
if((r[i]-R)%d) return -1;
R=(r[i]-R)/d*x%(m[i]/d)*M+R;
M*=m[i]/d;
R%=M;
}
R=(R+M)%M;if(!R) R=M;
return R;
}
int main()
{
n=read();
for(int i=1;i<=n;i++) {
a[i]=read();
pos[a[i]]=i;
}
for(int i=1;i<n;i++)
{
int x=pos[i];
int j=pos[i-1];
while(j!=x) {
j++;if(j>n) j=1;
if(a[j]>=i) r[i]++;
}
m[i]=n-i+1;r[i]%=m[i];
}
int Ans=Ex_CRT();
if(Ans==-1) printf("NIE\n");
else printf("%d\n",Ans);
return 0;
}