另
S=∑ai
一个人能看到第
i
个星星,那么他在下一个轮回能看到
这样的话就可以把
T
个星星,分成
每个环单独出来就可以了。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#define fi first
#define se second
using namespace std;
const int N=200010;
typedef long long ll;
typedef pair<ll,ll> pari;
int n,a[N],b[N],ans[N];
ll T,S,g,len;
map<ll,vector<int> > M;
map<ll,int> C;
ll gcd(ll x,ll y){
return y?gcd(y,x%y):x;
}
pari exgcd(ll x,ll y){
if(!y) return pari(1,0);
pari ret=exgcd(y,x%y);
return pari(ret.se,ret.fi-(x/y)*ret.se);
}
inline bool cmp(const int &x,const int &y){
return b[x]<b[y];
}
int main(){
scanf("%lld%d",&T,&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),S+=a[i];
a[1]=0;
for(int i=2;i<=n;i++)
a[i]=(a[i-1]+a[i])%T;
g=gcd(S,T); len=T/g;
for(int i=1;i<=n;i++){
if(C.count(a[i])) continue;
C[a[i]]=1;
M[a[i]%g].push_back(i);
}
for(auto u : M){
vector<int> V=u.se; int bg=u.fi;
if(V.size()==1){
ans[V[0]]=len; continue;
}
for(int i : V){
int cur=bg-a[i],dv=(a[i]-bg)/g;
ll A=T,B=S;
pari now=exgcd(A,B);
b[i]=(1LL*dv*now.se%len+len)%len;
}
sort(V.begin(),V.end(),cmp);
for(int i=0;i<V.size();i++){
int cur=V[i],nxt=V[(i+1)%V.size()];
ans[cur]=(b[nxt]-b[cur]+len)%len;
}
}
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}