wiki 1874 素数和最大

来源:互联网 发布:微软程序员认证 编辑:程序博客网 时间:2024/06/08 17:35
#include<cstdio>#include<cstring>#include<iostream>#include<iomanip>#include<queue>#include<cmath>#include<stack>#include<map>#include<set>#include<algorithm>#include<vector>using namespace std;const long long maxN = 200010;const long long maxn = 41000;const long long maxm = 300000;const long long INF = 1 << 30;struct Edge{    long long from, to, cap, flow, cost;};vector<Edge> edges;vector<long long> G[maxn];vector<long long> sushu;long long vis[maxn];long long result;long long n,sushu_size,mid_size,s,t;long long d[maxn],a[maxn];long long p[maxn];long long inq[maxn];bool panduan (long long n){    if(n==2) return true;    for(long long i = 2; i*i <= n; i++){        if(n%i==0) return false;    }    return true;}void addedge (long long from, long long to, long long cap, long long cost){    edges.push_back(Edge{from,to,cap,0,cost});    edges.push_back(Edge{to,from,0,0,-cost});    long long size = edges.size();    G[from].push_back(size-2);    G[to].push_back(size-1);}void init(){    cin >> n;    result = 0;    for(long long i = 2; i <= n; i++) {if(panduan(i)) sushu.push_back(i);}    long long i;    for(i = sushu.size()-1; sushu[i]*2 > n; i--) result += sushu[i];    sushu_size = i+1;    for(i = 0; sushu[i]*sushu[i]<=n; i++);    mid_size = i;    s = sushu_size;    t = sushu_size+1;    int aa = sushu_size+2;    memset(vis, 0, sizeof(vis));    for(i = 0; i < mid_size; i++){        for(long long j = mid_size; j < sushu_size; j++){            long long temp = 1;            while(temp*sushu[i] <= n) temp *= sushu[i];            long long ttemp = sushu[j];            while(ttemp * sushu[i] <= n) ttemp *= sushu[i];            if(temp + sushu[j] < ttemp){                addedge(i, j, 1, -(ttemp-temp-sushu[j]));                if(!vis[i]){                    addedge(s, i, 1, 0);                    addedge(i, aa, 1, 0);                    vis[i] = 1;                }                if(!vis[j]){                    addedge(j, t, 1, 0);                    vis[j] = 1;                }            }        }    }    addedge(aa, t, t, 0);}void solve (){    memset(a, 0, sizeof(a));    memset(p, -1, sizeof(p));    a[s] = INF;    while(true){        queue<long long> q;        q.push(s);        memset(inq, 0, sizeof(inq));        inq[s] = 1;        for(long long i = 0; i <= t+1; i++)d[i] = INF;        d[s] = 0;                while(!q.empty()){            long long u = q.front();            q.pop();            inq[u] = 0;            for(long long i = 0; i < G[u].size(); i++){                Edge& edge = edges[G[u][i]];                if(edge.cap > edge.flow && d[edge.to] > d[edge.from]+edge.cost){                    d[edge.to] = d[edge.from]+edge.cost;                    a[edge.to] = (a[edge.from] > edge.cap-edge.flow ? edge.cap-edge.flow : a[edge.from]);                    p[edge.to] = G[u][i];                    if(!inq[edge.to]){q.push(edge.to); inq[edge.to] = 1;}                }            }        }        if(d[t]==INF) break;        long long u = t;        while(u!=s){            edges[p[u]].flow += a[t];            edges[p[u]^1].flow -= a[t];            u = edges[p[u]].from;        }        result += -(d[t]*a[t]);    }}int main(int argc, const char * argv[]){//    long long count = 0;//    for(long long i = 2; i <= 200000; i++){//        if(panduan(i)) count++;//    }//    cout << count << endl;    init();    for(long long i = 0; i < sushu_size; i++){        if(sushu[i]*sushu[i]<=n) {            long long temp = sushu[i];            while(temp*sushu[i] <=n) temp *= sushu[i];            result += temp;        }        else{            result += sushu[i];        }    }    solve();    cout << result + 1 << endl;}

0 0