3308: 九月的咖啡店

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit:
159  Solved: 56
[Submit][Status][Discuss]

Description

深绘里在九份开了一家咖啡让,如何调配咖啡民了她每天的头等大事我们假设她有N种原料,第i种原料编号为i,调配一杯咖啡则需要在这里若干种兑在一起。不过有些原料不能同时在一杯中,如果两个编号为i,j的原料,当且仅当i与j互质时,才能兑在同一杯中。现在想知道,如果用这N种原料来调同一杯咖啡,使用的原料编号之和最大可为多少。

Input

一个数字N

Output

如题

Sample Input

10

Sample Output

30

HINT

1<=N<=200000

Source

Solution

从N的范围,难以直接看出是网络流,但仔细分析,还是可以想到的

比较厉害的建图,首先需要两个结论

1.一个数的质因子,最多有两个

2.并且这两个质因子,一个小于$\sqrt{n}$,一个大于$\sqrt{n}$

那么可以考虑筛出1~n的素数

考虑建二分图

源向小于$\sqrt{n}$的质数连边,容量为1,费用为0

大于$\sqrt{n}$的质数向汇连边,容量为1,费用为0

小于$\sqrt{n}$的质数$a$向大于$\sqrt{n}$的质数$b$连边,容量为1,费用为$V_{ab}-V_{a}-V_{b}$

$V_{a}$表示单独选$a$的最大收益$V_{a}=a^{lgn/lga}$

$V_{b}$表示单独选$b$的最大收益$V_{b}=b$

$V_{ab}$表示同时选$a$和$b$的最大收益$V_{ab}=a^{lg(n/b)/lga}*b$

这样效率并不是特别的高,那么还可以加上两个优化:

1.如果一个质数>n/2,那么它只能单独选,不用连边

2.如果一条边的费用<0,那么完全可以不连

然后考虑 最大费用最大流 即可

Code

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; char ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define maxn 200010
#define maxm 200000*10+10
#define inf 0x7fffffff
int n,ans;
struct Edgenode{int next,to,from,cap,cost;}edge[maxm];
int head[maxn],cnt=;
//init
inline void add(int u,int v,int w,int c)
{
cnt++; edge[cnt].next=head[u]; head[u]=cnt;
edge[cnt].from=u; edge[cnt].to=v; edge[cnt].cap=w; edge[cnt].cost=c;
}
inline void insert(int u,int v,int w,int c)
{add(u,v,w,c); add(v,u,,-c);}
//addedge
bool mark[maxn];int dis[maxn],S,T;
inline bool spfa()
{
queue<int>q; memset(mark,,sizeof(mark));
for (int i=S; i<=T; i++) dis[i]=-inf;
q.push(S); mark[S]=; dis[S]=;
while (!q.empty())
{
int now=q.front(); q.pop();
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]<dis[now]+edge[i].cost)
{
dis[edge[i].to]=dis[now]+edge[i].cost;
if (!mark[edge[i].to])
mark[edge[i].to]=,q.push(edge[i].to);
}
mark[now]=;
}
return dis[T]>;
}
inline int dfs(int loc,int low)
{
mark[loc]=;
if (loc==T) return low;
int w,used=;
for (int i=head[loc]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==dis[loc]+edge[i].cost && !mark[edge[i].to])
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w; used+=w;
ans+=w*edge[i].cost; if (used==low) return low;
}
return used;
}
inline void zkw()
{
int tmp=;
while (spfa())
{
mark[T]=;
while (mark[T])
memset(mark,,sizeof(mark)),tmp+=dfs(S,inf);
}
}
//MaxflowMaxcost
bool flag[maxn]; int prime[maxn],tot;
inline void prework(int maxx)
{
flag[]=;
for (int i=; i<=maxx; i++)
{
if (!flag[i]) prime[++tot]=i;
for (int j=; j<=tot && i*prime[j]<=maxx; j++)
{
flag[i*prime[j]]=;
if (!(i%prime[j])) break;
}
}
}
//get prime
inline int calc(int n,int x)
{
long long t=x;
while (t*x<=n) t=t*x;
return t;
}
//calc
inline void make()
{
S=,T=tot+; int pos=;
for (int i=; i<=tot; i++)
{
if (prime[i]>=n/) {ans+=prime[i];continue;}
if ((long long)prime[i]*prime[i]<=n)
insert(S,i,,),ans+=calc(n,prime[i]);
else
pos=(!pos)?i:pos,insert(i,T,,),ans+=prime[i];
}
for (int i=; i<pos; i++)
for (int j=pos; j<=tot; j++)
{
if ((long long)prime[i]*prime[j]>n) break;
int tmp=calc(n/prime[j],prime[i])*prime[j]-calc(n,prime[i])-prime[j];
if (tmp>) insert(i,j,,tmp);
}
}
//build
int main()
{
n=read();
prework(n);
make();
zkw();
printf("%d\n",ans+);
return ;
}

忽略桑心病狂的inline.. && 自己YY的最大费用最大流...好像还可以?

【BZOJ-3308】九月的咖啡店 最大费用最大流 + 线性筛素数的更多相关文章

  1. 【BZOJ 3308】 3308: 九月的咖啡店 (费用流|二分图最大权匹配)

    3308: 九月的咖啡店 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 244  Solved: 86 Description 深绘里在九份开了一家咖 ...

  2. bzoj 3308: 九月的咖啡店【最大费用最大流】

    费用流里spfa最后的判断要写成dis[t]>=0而不是dis[t]!=-inf否则会WAWAWA-- #include<iostream> #include<cstdio&g ...

  3. bzoj 3308 九月的咖啡店

    题目大意: 求若干个<=n的数 两两互质 使和最大 求这个最大的和 思路: 显然,得到两个结论 1 最终的所有数都只能分解为两个质因数 2 这两个质因数 一个<根号n 一个>根号n ...

  4. BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流

    传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...

  5. BZOJ 1061 志愿者招募(最小费用最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...

  6. bzoj 1070 [SCOI2007]修车(最小费用最大流)

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3515  Solved: 1411[Submit][Status] ...

  7. BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)

    不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...

  8. bzoj 3171: [Tjoi2013]循环格 最小费用最大流

    题目大意: http://www.lydsy.com/JudgeOnline/problem.php?id=3171 题解: 首先我们很容易发现一个结论: 出现完美循环当且仅当所有点的出入度均为1 所 ...

  9. bzoj 1070: [SCOI2007]修车【最小费用最大流】

    一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...

随机推荐

  1. 小心 CSS3 Transform 引起的 z-index "失效"

    https://www.douban.com/note/343402554/ http://www.jb51.net/css/255811.html 最后我直接removeClass;把transfo ...

  2. Broadmann分区

    来源: http://blog.sina.com.cn/s/blog_60a751620100k2hj.html Brodmann areas Name 中文名 Function 1 Somatose ...

  3. 浅析jQuery删除节点的三个方法

    jQuery提供了三种删除节点的方法,即remove(),detach()和empty().测试所用HTML代码:[html] view plaincopy<p title="选择你最 ...

  4. JQuery阻止事件冒泡---阻止后续代码执行

    (1)什么是事件起泡 首先你要明白一点,当一个事件发生的时候,该事件总是有一个事件源,即引发这个事件的对象,一个事件不能凭空产生,这就是事件的发生. 当事件发生后,这个事件就要开始传播.为什么要传播呢 ...

  5. CSS IE6/7/8, Firefox, Safari, Chrome, Opera Hack使用简要归纳(转)

    网上有很多关于IE6/7/8, Firefox, Safari, Chrome, Opera CSS Hack的文章,但我觉得太过繁杂,要不给出一张看也看不懂的CSS Hack归纳表,要不就是给出一大 ...

  6. git push ERROR: missing Change-Id in commit message footer

    今天上传代码时候报告错误:$ git push origin HEAD:refs/for/branch*Counting objects: 7, done.Delta compression usin ...

  7. ReactNative真机运行指南

    ReactNative真机运行指南 注意在iOS设备上运行React Native应用需要一个Apple Developer account并且把你的设备注册为测试设备.本向导只包含React Nat ...

  8. NPOI导出

    <body> @using (Html.BeginForm("ImportCommentsFile", "CommentsManage", Form ...

  9. Android开发之Notification通知

    消息通知使我们很常见的,当收到一条消息的时候,通知栏会显示一条通知: 直接看代码: public class MainActivity extends Activity { private Notif ...

  10. C#中的System.Speech命名空间初探

    本程序是口算两位数乘法,随机生成两个两位数,用语音读出来.然后开启语音识别,接受用户输入,知道答案正确关闭语音识别.用户说答案时,可以说“再说一遍”重复题目. 关键是GrammarBuilder和Ch ...