妈的
神仙网络流
官方题解给了一个美妙的性质:只能选质数的幂,或者含有之多两个质数的值且两个数一个小于sqrt一个大于sqrt
然后就可以模拟退火了
但是很明显不需要(官方题解好坏坏)
费用流!
这不是冲突关系吗
啥子可以表示冲突关系?网络流啊!
然后费用流增广唯一剩下的可行流
于是是最大费用可行流
#include
using namespace std;
typedef int INT;
#define int long long
const int INF=1e17;
const int N=2e6+100;
int vis[N]={};
int Prime[N]={};
int idx=0;
void Pre(int maxn){
for(int i=2;i<=maxn;i++){
if(!vis[i]){
idx++;
Prime[idx]=i;
}
for(int j=1;j<=idx&&Prime[j]*i<=maxn;j++){
vis[i*Prime[j]]=1;
if(i%Prime[j]==0)break;
}
}
}
struct Front_star{
int u,v,w,c,nxt;
}e[N<<2];
int cnt=1;
int n;
int first[N]={};
void addedge(int u,int v,int w,int c){
cnt++;
e[cnt].u=u;
e[cnt].v=v;
e[cnt].w=w;
e[cnt].c=c;
e[cnt].nxt=first[u];
first[u]=cnt;
}
void add(int u,int v,int w,int c){
addedge(u,v,w,c);
addedge(v,u,0,-c);
}
int S=0;
int T=N-1;
int ans=0;
vector A,B;
int dis[N];
int inqueue[N];
int pre[N];
queue Q;
bool SPFA(){
memset(pre,0,sizeof(pre));
for(int i=S;i<=T;i++){
dis[i]=-INF;
}
dis[S]=0;
Q.push(S);
while(!Q.empty()){
int x=Q.front();
Q.pop();
inqueue[x]=0;
for(int i=first[x];i;i=e[i].nxt){
int v=e[i].v;
if(e[i].w&&dis[x]+e[i].c>dis[v]){
dis[v]=dis[x]+e[i].c;
pre[v]=i;
if(!inqueue[v]){
Q.push(v);
inqueue[v]=1;
}
}
}
}
return dis[T]>=0;
}
void MCMF(int ans){
int dat=0;
while(SPFA()){
int s=INF;
for(int i=pre[T];i;i=pre[e[i^1].v])s=min(s,e[i].w);
for(int i=pre[T];i;i=pre[e[i^1].v]){
e[i].w-=s;
e[i^1].w+=s;
}
dat+=s;
ans+=dis[T]*s;
}
cout<n)ans+=Prime[i];
else{
if(t*t<=n){
ans+=Get(n,t);
add(S,i,1,0);
A.push_back(i);
}
else{
add(i,T,1,0);
ans+=t;
B.push_back(i);
}
}
}
for(int i=0;iGet(n,a)+b){
add(A[i],B[j],1,tmp-Get(n,a)-b);
}
}
else break;
}
}
}
INT main(){
freopen("test.in","r",stdin);
cin>>n;
Pre(n);
Build_Gra();
MCMF(ans);
}