bzoj-3308 九月的咖啡店

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

数据范围:$1\le N \le 2\cdot 10^5$。


想法

神仙题.....

主要神仙在,两个根本没法证(至少我现在不会2019.6.19)的性质。

1.每个数最多只包含两个质数

2.如果包含两个质数那么一个小于$\sqrt{n}$一个大于$\sqrt{n}$。

这咋证.....

如果考场上猜到了这两个性质,那就容易多了。

我们把所有小于根号$n$与所有大于根号$n$的素数之间建立二分图。

暴力建肯定是不行,发现如果这两个数的答案比原来大,我们再连边。

这样就好了嗷~

最后费用流即可。

代码

#include <bits/stdc++.h>
#define inf (1<<30)
#define N 1000010
using namespace std;
typedef long long ll;
int S,T,n;
int to[N<<1],nxt[N<<1],val[N<<1],tot=1,cst[N<<1],fr[N],head[N];
int pre[N],dis[N];
bool vis[N];
int prime[N]; bool vis_prime[N];
inline void Add(int x,int y,int z,int c) {to[++tot]=y; fr[tot]=x; val[tot]=z; cst[tot]=c; nxt[tot]=head[x]; head[x]=tot;}
inline void add(int x,int y,int z,int c) {Add(x,y,z,c); Add(y,x,0,-c);}
bool spfa()
{
queue<int>q; while(!q.empty()) q.pop();
for(int i=0;i<=T;i++) dis[i]=inf,vis[i]=false;
memset(pre,0,sizeof pre);
dis[S]=0; vis[S]=true; q.push(S);
while(!q.empty())
{
int x=q.front(); q.pop();
vis[x]=false;
for(int i=head[x];i;i=nxt[i]) if(val[i] && dis[to[i]] > dis[x]+cst[i])
{
pre[to[i]]=i;
dis[to[i]] = dis[x] + cst[i];
if(!vis[to[i]]) q.push(to[i]),vis[to[i]]=true;
}
}
return dis[T] < 0;
}
ll minf()
{
int flow = inf;
for(int i=T;i!=S;i=to[pre[i]^1]) flow=min(flow,val[pre[i]]);
for(int i=T;i!=S;i=to[pre[i]^1]) val[pre[i]]-=flow,val[pre[i]^1]+=flow;
return flow * dis[T];
}
// ll minf()
// {
// ll ans=0;
// int i=pre[T],mdl=inf;
// while(i)
// {
// mdl=min(mdl,val[i]);
// i=pre[fr[i]];
// }
// i=pre[T];
// while(i)
// {
// val[i]-=mdl;
// val[i^1] += mdl;
// ans += (ll)mdl * cst[i];
// i=pre[fr[i]];
// }
// return ans;
// }
int qpow(int x,int y)
{
int ans=1;
while(y)
{
if(y&1) ans=ans*x;
y>>=1;
x=x*x;
}
return ans;
}
int Lmt(int x,int y) {int re; for(re=x;1ll*re*x<=y;re*=x); return re;}
void init_prime(int n)
{
for(int i=2;i<=n;i++)
{
// printf("%d\n",i);
if(!vis_prime[i]) prime[++prime[0]]=i;
for(int j=1;j<=prime[0] && (ll)i*prime[j] <= n;j++)
{
// printf("%d %d %d\n",i,prime[j],prime[j] * i);
vis_prime[i*prime[j]]=true;
// printf("%d %d %d\n",i,prime[j],prime[j]*i);
if(i%prime[j]==0) break;
}
}
}
ll ans=0;
void Build()
{
S=prime[0]+1; T=S+1;
int pos=0;
for(int i=1;i<=prime[0];i++)
{
if(prime[i] >= n/2) {ans += prime[i]; continue;}
if((ll)prime[i] * prime[i] <= n) add(S,i,1,0),ans += Lmt(prime[i],n);
else
{
if(!pos) pos=i;
add(i,T,1,0); ans += prime[i];
}
}
// cout << pos << endl ;
for(int i=1;i<pos;i++)
for(int j=pos;j<=prime[0];j++)
{
if((ll)prime[i] * prime[j] > n) break;
int mdl = Lmt(prime[i],n/prime[j]) * prime[j] - Lmt(prime[i],n) - prime[j];
// cout << mdl << endl ;
if(mdl > 0) add(i,j,1,-mdl);
}
// cout << ans << endl ;
}
ll Calc()
{
while(spfa())
{
ll tmp=minf();
if(tmp<0) ans-=tmp;
}
return ans;
}
int main()
{
// freopen("sum.in","r",stdin);
// freopen("sum.out","w",stdout);
cin >> n ;
// puts("A");
init_prime(n);
Build();
cout << Calc()+1 << endl ;
// fclose(stdin);
// fclose(stdout);
return 0;
}

小结:这种题就要大胆猜结论,如果能小心验证那就证一证,不然的话觉得对就直接拿来用就好了。

[bzoj3308]九月的咖啡店_欧拉筛素数_费用流的更多相关文章

  1. [CF261E]Maxim and Calculator_搜索_欧拉筛素数_动态规划

    Maxim and Calculator 题目链接:https://www.luogu.org/problem/CF261E 数据范围:略. 题解: 考试的时候只会暴力,学弟太强了$\%\%\% Or ...

  2. POJ-3126.PrimePath(欧拉筛素数打表 + BFS)

    给出一篇有关素数线性筛和区间筛的博客,有兴趣的读者可以自取. 本题大意: 给定两个四位的素数,没有前导零,每次变换其中的一位,最终使得两个素数相等,输出最小变换次数.要求变换过程中的数也都是素数. 本 ...

  3. 洛谷 P3383 【模板】线性筛素数-线性筛素数(欧拉筛素数)O(n)基础题贴个板子备忘

    P3383 [模板]线性筛素数 题目描述 如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内) 输入输出格式 输入格式: 第一行包含两个正整数N.M,分别表示查询的范 ...

  4. [bzoj4818][Sdoi2017]序列计数_矩阵乘法_欧拉筛

    [Sdoi2017]序列计数 题目大意:https://www.lydsy.com/JudgeOnline/problem.php?id=4818. 题解: 首先列出来一个递推式子 $f[i][0]$ ...

  5. Java实现欧拉筛与花里胡哨求质数高级大法的对比

    我也不清楚这是什么高级算法,欧拉筛是昨天有位大佬,半夜无意间告诉我的 欧拉筛: 主要的含义就是我把这个数的所有倍数都弄出来,然后下次循环的时候直接就可以跳过了 import java.text.Sim ...

  6. BZOJ_2186_[Sdoi2008]沙拉公主的困惑_欧拉函数

    BZOJ_2186_[Sdoi2008]沙拉公主的困惑_欧拉函数 Description 大富翁国因为通货膨胀,以及假钞泛滥,政府决定推出一项新的政策:现有钞票编号范围为1到N的阶乘,但是,政府只发行 ...

  7. 埃氏筛优化(速度堪比欧拉筛) + 洛谷 P3383 线性筛素数 题解

    我们一般写的埃氏筛消耗的时间都是欧拉筛的三倍,但是欧拉筛并不好想(对于我这种蒟蒻) 虽然 -- 我 -- 也可以背过模板,但是写个不会的欧拉筛不如写个简单易懂的埃氏筛 于是就有了优化 这个优化还是比较 ...

  8. noip复习——线性筛(欧拉筛)

    整数的唯一分解定理: \(\forall A\in \mathbb {N} ,\,A>1\quad \exists \prod\limits _{i=1}^{s}p_{i}^{a_{i}}=A\ ...

  9. 【BZOJ 2190】【SDOI 2008】仪仗队 欧拉筛

    欧拉筛模板题 #include<cstdio> using namespace std; const int N=40003; int num=0,prime[N],phi[N]; boo ...

随机推荐

  1. JS中鼠标左右键以及中键的事件

    在三维场景中有时候需要判断鼠标的事件,除了使用的click事件,只有鼠标左键有效,而右键无效.而对于onmousedown.onmouseup的时候鼠标的事件左键/右键有效.详细请看w3c上的资料. ...

  2. 二分查找算法java

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元 ...

  3. 目录扫描工具DirBuster

    DirBuster是用来探测web服务器上的目录和隐藏文件的.因为DirBuster是采用java编写的,所以运行前要安装上java的环境. 来看一下基本的使用: ①:TargetURL下输入要探测网 ...

  4. css3-flex-box(2)

    使用方法 使用Flexbox布局只要在父容器元素上设置display属性: .flex-container { display: -webkit-flex; /* Safari */ display: ...

  5. 条款40:明智而审慎地使用多重继承(use multiple inheritance judiciously)

    NOTE: 1.多重继承比单一继承复杂.它可能导致新的歧义性,以及对virtual继承的需要. 2.virtual 继承会增加大小 速度 初始化(及赋值)复杂度等等成本.如果virtual base ...

  6. 时间格式的处理和数据填充和分页---laravel

    时间格式文档地址:http://carbon.nesbot.com/docs/ 这是些时间格式,只需要我们这么做就可以 我们在模板层,找到对应的模型对象那里进行处理就可以啦 2018-11-08 16 ...

  7. 【支付宝支付】扫码付和app支付,回调验证签名失败问题

    在检查了参数排序,编码解码,文件编码等问题后,发现还是签名失败,最后找出原因: 扫码付和app支付采用的支付宝公钥不一样   Pid和公钥管理里面:   开放平台密钥界面和开放平台应用界面的密钥应该一 ...

  8. Cocos2d-x学习资料集锦

    Cocos2d-x学习资料集锦: 1.Cocos2d-x官方中文文档:https://github.com/chukong/cocos-docs/blob/master/catalog/zh.md 推 ...

  9. 2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F题

    The Heaviest Non-decreasing Subsequence Problem 解题心得 这个题就是一个简单的动态规划,非递减最长子序列的改版(加一个权重),只要把权重为5的改成5个权 ...

  10. The North American Invitational Programming Contest 2018 H. Recovery

    Consider an n \times mn×m matrix of ones and zeros. For example, this 4 \times 44×4: \displaystyle \ ...