显然应当预处理出所有的答案,考虑在n−1的最大生成树上加边得到n的最大生成树,即对每一条边
考虑对于n的一个因数
所以每次枚举当前n的所有因数连边,之后让lct做一点微小的工作即可,复杂度
#include<algorithm>
#include<iostream>
#include<cstring>
#include<climits>
#include<cstdio>
//--container
using namespace std;
#include<stack>
typedef long long ll;
const int up=1000000;
//--
#define clr(a) memset(a,0,sizeof(a))
struct nd{nd* fa,* gfa,* cd[2];int mi,wg;bool fg;}ndr[300010],*id[100010];
struct eg{int v,nx;}gp[1200000];
ll rs[100010],ts=0;int n,tn,cnt,hd[100010];stack<nd*>sk;
void psh(int u,int v){
++cnt;gp[cnt].v=v;
gp[cnt].nx=hd[u],hd[u]=cnt;
};
nd* _new(){
nd* t;if(!sk.empty()){
t=sk.top();sk.pop();t->cd[0]=t->cd[1]=t->fa=t->gfa=0,t->fg=0;
return t;
};
ndr[tn].cd[0]=ndr[tn].cd[1]=ndr[tn].fa=ndr[tn].gfa=0,ndr[tn].fg=0;
return &ndr[tn++];
};
void _delete(nd* t){sk.push(t);};
inline void mis(nd* v){
v->mi=min(v->wg,min(v->cd[0]?v->cd[0]->mi:up,v->cd[1]?v->cd[1]->mi:up));
};
void fgs(nd* v){
if(v->cd[0])v->cd[0]->fg^=1;
if(v->cd[1])v->cd[1]->fg^=1;
swap(v->cd[0],v->cd[1]),v->fg=0;
};
void tgs(nd* v){if(v->fa){tgs(v->fa);v->gfa=v->fa->gfa;}if(v->fg)fgs(v);};
void rot(nd* v){
int i,j,d;nd* f=v->fa,* g=f->fa;d=f->cd[0]==v?0:1;
if(g)g->cd[g->cd[0]==f?0:1]=v;v->fa=g,f->fa=v;
if(v->cd[d^1])v->cd[d^1]->fa=f;f->cd[d]=v->cd[d^1],v->cd[d^1]=f;mis(f),mis(v);
};
void spy(nd* v,nd* x){
int i,j,a,b;nd* f,* g;for(tgs(v);v->fa!=x;){
f=v->fa,g=f->fa;
if(x==g){rot(v);break;};
a=f->cd[0]==v?0:1,b=g->cd[0]==f?0:1;
if(a==b)rot(f),rot(v);
else
rot(v),rot(v);
}
};
void access(nd* v){
nd* d,* k;for(d=0;v;){
spy(v,0);if(v->cd[1])v->cd[1]->fa=0,v->cd[1]->gfa=v;
v->cd[1]=d;if(d)d->fa=v;mis(v),d=v,v=v->gfa;
}
};
void mkrot(nd* v){access(v);spy(v,0);v->gfa=0,v->fg^=1;};
nd* _dfs(nd* v,int x){
if(v->wg==x)return v;
if(v->cd[0]&&v->cd[0]->mi==x)return _dfs(v->cd[0],x);
return _dfs(v->cd[1],x);
};
nd* _ldfs(nd* v){
if(v->fg)fgs(v);
return v->cd[1]?_ldfs(v->cd[1]):v;
};
nd* _rdfs(nd* v){
if(v->fg)fgs(v);
return v->cd[0]?_rdfs(v->cd[0]):v;
};
nd* _fl(nd* v){return v->cd[0]?_ldfs(v->cd[0]):v->fa;};
nd* _fr(nd* v){return v->cd[1]?_rdfs(v->cd[1]):v->fa;};
void _cut(nd* v){
if(v->fg)fgs(v);spy(v,0);nd* l=_fl(v),* r=_fr(v);
spy(l,v);spy(r,v);l->fa=r->fa=l->gfa=r->gfa=0;
_delete(v);
};
void _link(nd* u,nd* v,int x){
nd* d=_new();d->mi=d->wg=x;
access(u);spy(u,0);d->gfa=u;
mkrot(v);v->gfa=d;access(v);spy(d,0);
};
void _cl(nd* u,nd* v,int x){
int t;mkrot(u);access(v);spy(v,0);
if(v->mi>=x)return;
ts+=(x-v->mi);_cut(_dfs(v,v->mi));_link(u,v,x);
};
void clit(){
int i,j,d;bool fg;for(cnt=0,i=1;i<=100000;++i){
for(j=i;j<=100000;j+=i)psh(j,i);
}
for(i=1,ts=0;i<=100000;++i){
id[i]=_new();id[i]->mi=id[i]->wg=up;
if(i>1){
j=gp[hd[i]].nx;ts+=gp[j].v;
_link(id[i],id[gp[j].v],gp[j].v);
for(j=gp[j].nx;j;j=gp[j].nx)
_cl(id[i],id[gp[j].v],gp[j].v);
}
rs[i]=ts;
}
};
bool cl(){
int n;if(scanf("%d",&n)==-1)return 0;
printf("%d\n",rs[n]);
return 1;
};
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
for(clit();cl(););
return 0;
};