首先可以发现,如果 xi>xi+1 那么 xi 就是没用的,所以我们就倒过来求一个递减的序列
然后考虑第
i
次操作后的数列,肯定是由第
而那个前缀也是由之前的某个前缀得到的,那么就二分一下,记一下每次操作会执行几次(也就是被后面的操作覆盖几次)
瞎搞一下
因为每次操作最多二分log次,所以总复杂度是 O(nlog2n) 的
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
int n,q,t;
ll b[N],Q[N],a[N],c[N];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void read(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void read(ll &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void work(ll x,ll y){
int p=upper_bound(Q,Q+1+t,x)-Q-1;
if(!p) a[1]+=y,a[x+1]-=y;
else c[p]+=y*(x/Q[p]),work(x%Q[p],y);
}
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
read(n); read(q);
if(q==0){
for(int i=1;i<=n;i++) printf("%d\n",1); return 0;
}
for(int i=1;i<=q;i++) read(b[i]);
Q[++t]=b[q];
for(int i=q-1;i;i--){
if(b[i]>=Q[t]) continue;
Q[++t]=b[i];
}
if(n<Q[t]) Q[++t]=n; reverse(Q+1,Q+1+t);
c[t]=1;
for(int i=t;i>1;i--)
c[i-1]+=c[i]*(Q[i]/Q[i-1]),work(Q[i]%Q[i-1],c[i]);
for(int i=1;i<=n;i++) a[i]+=a[i-1];
for(int i=1;i<=Q[1];i++) a[i]+=c[1];
for(int i=1;i<=n;i++) printf("%lld\n",a[i]);
return 0;
}