题解:P10886 【MX-S3-T2】「FeOI Round 1」Journey
看题目有点像根号分治,但是观察数据范围,得出算法时间复杂度应该为
再观察
考虑计算
考虑怎么优化,令
for(int c=1;c<=n;c++)for(int t=1;c*t<=n;t++){
b[c*t+1]+=t;if(c*(t+1)+1<=n)b[c*(t+1)+1]-=t;
}
这样不好优化,但是我们可以观察到这段代码和下面这段代码是等价的:
for(int c=1;c<=n;c++)for(int t=1;c*t<=n;t++){
b[c*t+1]++;
}
至于为什么是等价的,留作习题答案略,读者自证不难。\
其实就是把
然后上面的代码得出的
代码如下:
#include<bits/stdc++.h>
#define ll long long
#define il inline
#define reg register
#define fmod(x) ((x)>mod?(x)-mod:(x))
using namespace std;
il void fread(ll &X){ll A=1;X=0;char C=getchar();while(!isdigit(C)&&C!='-')C=getchar();if(C=='-')A=-1,C=getchar();while(isdigit(C))X=(X<<1)+(X<<3)+(C^48),C=getchar();X*=A;}
il void fout(ll X){if(X<0)putchar('-'),X=-X;if(!X){putchar('0'),putchar(' ');return;}char C[25]{};int Len=0;while(X)C[++Len]=X%10+'0',X/=10;for(;Len;--Len)putchar(C[Len]);putchar(' ');}
const ll mod = 1e9+7,N=2e7+5;
ll n, A, B, C, g[N],ans=0;
ll sg,sgi,tmp,b[N],cnt=0;
bitset<N>v;int c[N],d[N],pri[N];
int main(){
fread(n),fread(A),fread(B),fread(C),fread(g[n]);
for(reg int i=n-1;i>=1;i--)g[i]=fmod(A*g[i+1]%mod*g[i+1]%mod+B*g[i+1]%mod+C);
d[1]=1;for(reg ll i=2;i<=n;i++){
if(!v[i]) pri[++cnt]=i,d[i]=2,c[i]=1;
for(reg ll j=1;j<=cnt&&i*pri[j]<=n;j++){
v[i*pri[j]]=1;if(i%pri[j]==0){
c[i*pri[j]]=c[i]+1;d[i*pri[j]]=d[i]/(c[i]+1)*(c[i]+2);break;
}d[i*pri[j]]=d[i]*2;c[i*pri[j]]=1;
}
}
for(reg int i=1;i<=n;i++){
sg=fmod(sg+g[i]),sgi=fmod(sgi+g[i]*i%mod);
b[i]=d[i-1];b[i]=fmod(b[i]+b[i-1]);
tmp=(n-i+1)*g[i]%mod;
ans=fmod(ans+tmp*b[i]%mod);
}ans=fmod(ans+n*(fmod(n*sg%mod+sg)-sgi+mod)%mod);fout(ans);
return 0;
}