zoukankan      html  css  js  c++  java
  • BZOJ 3308 毒瘤结论 网络流

    结论:在答案集合中的数其质因数最多有两个 且有两个的话一个>n1/2一个<n1/2

    这样我们就可以把所有质数筛出来 弄成二分图 左边是<n1/2右边是>n1/2

    所以先把单个质因子的答案全部加上 再考虑两个质因子的一个数会不会比一个质因子的两个数更优

    如果更优 则建边 再求最大流

    注意最后答案要加上特殊的1

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    const int N=200005;
    const int inf=0x7fffffff;
    int n,val[N],cnt,prime[N],tot,last[N],s,t,dis[N],pre[N];
    struct edge{int to,from,c,w,next;}e[N*5];
    queue <int> q;
    bool not_prime[N],vis[N];
    LL ans;
    void get_prime(int n)
    {
        for (int i=2;i<=n;i++)
        {
            if (!not_prime[i]) prime[++tot]=i;
            for (int j=1;j<=tot&&i*prime[j]<=n;j++)
            {
                not_prime[i*prime[j]]=1;
                if (i%prime[j]==0) break;
            }
        }
    }
     
    int get_val(int x,int y)
    {
        if (x*y>n) return 0;
        int w=x;
        while ((LL)w*x*y<=(LL)n) w*=x;
        return w*y;
    }
     
    void addedge(int u,int v,int c,int w)
    {
        e[++cnt].from=u;e[cnt].to=v;e[cnt].c=c;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;
        e[++cnt].from=v;e[cnt].to=u;e[cnt].c=0;e[cnt].w=-w;e[cnt].next=last[v];last[v]=cnt;
    }
     
    bool spfa()
    {
        for (int i=s;i<=t;i++) dis[i]=-inf;
        dis[s]=0;vis[s]=1;q.push(s);
        while (!q.empty())
        {
            int u=q.front();q.pop();
            for (int i=last[u];i;i=e[i].next)
                if (e[i].c&&dis[u]+e[i].w>dis[e[i].to])
                {
                    dis[e[i].to]=dis[u]+e[i].w;
                    pre[e[i].to]=i;
                    if (!vis[e[i].to]) q.push(e[i].to),vis[e[i].to]=1;
                }
            vis[u]=0;
        }
        if (dis[t]==-inf) return 0;
        else return 1;
    }
     
    void mcf()
    {
        if (dis[t]>0) ans+=dis[t];
        int x=t;
        while (x!=s)
        {
            e[pre[x]].c--;
            e[pre[x]^1].c++;
            x=e[pre[x]].from;
        }
    }
     
    int main()
    {
        scanf("%d",&n);
        get_prime(n);
        int w=sqrt(n);
        while (prime[tot]>n/2) ans+=prime[tot],tot--;
        s=0;t=tot+1;cnt=1;
        for (int i=1;i<=tot;i++)
        {
            ans+=val[i]=get_val(prime[i],1);
            if (prime[i]<=w) addedge(s,i,1,0);
            else addedge(i,t,1,0);
        }
        for (int i=1;i<=tot&&prime[i]<=w;i++)
            for (int j=tot;j&&prime[j]>w;j--)
            {
                int v=get_val(prime[i],prime[j]);
                if (v>val[i]+val[j]) addedge(i,j,1,v-val[i]-val[j]);
            }
        while (spfa()) mcf();
        printf("%lld",ans+1);
        return 0;
    }
    View Code
  • 相关阅读:
    vuex之store拆分即多模块状态管理
    vue项目中使用vueX
    vue中父子组件的参数传递和应用
    VUE中使用vue-awesome-swiper
    VUE真实项目中常用的生命周期和参数
    VUE生命周期
    vue+mockjs 模拟数据,请求回调的应用
    Vue项目搭建与部署还有调试插件Vue.js devtools
    tableTD中添加对角斜线
    前端面试题及答案,理论知识
  • 原文地址:https://www.cnblogs.com/Aragaki/p/10615258.html
Copyright © 2011-2022 走看看