我们肯定是要先求出来一个位置被加的次数,然后和权值乘一下就行。
对于一个位置 \(i\),右端点 \(b\) 肯定是随便选,一共 \(n-i+1\) 种情况。再是对于每一种步长 \(c\),左端点 \(a\) 都有 \(\left\lceil\dfrac{i}{c}\right\rceil\) 种取值,暴力计算,时间复杂度 \(O(n^2)\)。(提交记录)
考虑如何优化,对于第 \(i\) 个位置,设 $s_i = \sum_{c=1}^{n}{ \left\lceil\dfrac{i}{c}\right\rceil} $,那对于一个 \(c\),如果 \(\left\lceil\dfrac{i}{c}\right\rceil > \left\lceil\dfrac{i-1}{c}\right\rceil\),那么 \(i-1\) 一定是 \(c\) 的倍数。所以,\(i-1\) 有几个因数,\(s_{i}\) 就会变大多少,即 \(s_i = s_{i-1} + d_{i-1}\)。直接欧拉筛即可。
代码
#include<bits/stdc++.h>
using namespace std;
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
char ch=getchar();
T f=1;x=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x*=f;rd(args...);
}
const int N=2e7+5,mod=1e9+7;
int n,a,b,c,gn;
int t[N],ans;
int pri[N],cnt,d[N],num[N];
bool vis[N];
inline void Euler(){
d[1]=num[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
pri[++cnt]=i;
d[i]=2,num[i]=1;
}
for(int j=1;j<=cnt&&pri[j]*i<=n;j++){
vis[pri[j]*i]=1;
if(i%pri[j]==0){
num[i*pri[j]]=num[i]+1;
d[i*pri[j]]=d[i]/num[i*pri[j]]*(num[i*pri[j]]+1);
break;
}
num[i*pri[j]]=1;
d[i*pri[j]]=d[i]*2;
}
}
}
signed main(){
rd(n,a,b,c,gn);
t[1]=n;Euler();
for(int i=2;i<=n;i++)t[i]=t[i-1]+d[i-1];
ans=1ll*gn*t[n]%mod;
for(int i=n-1;i>=1;i--){
gn=(1ll*a*gn%mod*gn%mod+1ll*b*gn%mod+c)%mod;
(ans+=1ll*gn*t[i]%mod*(n-i+1)%mod)%=mod;
}printf("%d\n",ans);
return 0;
}