2118: 墨墨的等式

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1283  Solved: 496

Description

墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N、{an}、以及B的取值范围,求出有多少B可以使等式存在非负整数解。

Input

输入的第一行包含3个正整数,分别表示N、BMin、BMax分别表示数列的长度、B的下界、B的上界。输入的第二行包含N个整数,即数列{an}的值。

Output

输出一个整数,表示有多少b可以使等式存在非负整数解。

Sample Input

2 5 10
3 5

Sample Output

5

HINT

对于100%的数据,N≤12,0≤ai≤5*10^5,1≤BMin≤BMax≤10^12。

  1. /*
  2. 一开始就没想到是个最短路。
  3. 题目可以这样变化一下:n个物品,可以用0-,正无穷,问[l,r]区间内有多少价值可以凑出来。
  4. 联系到最短路上面:
  5. 任选一个ai>0,如果一个价值k∗ai+x(0≤x<ai,k≥0)可以被凑出来,那么显然(k+1)∗ai+x,(k+2)∗ai+x,...都可以被凑出来(这样x的范围就是小于ai了)
  6. 显然如果我们对于每个x都找到最小的k满足k∗ai+x可以被凑出来,这个问题就解决了,如果满足凑出x的最小花费是大于b的,那么就不能在[l,r]区间内凑出mn*k+x,这个数了,否则的话,就计算[l,r]内有多少个可以凑出来。
  7. 最短路,spfa
  8. 时间复杂度O(n∗ai∗log2ai)
  9. 因为复杂度与ai有关,所以我们就选择最小的ai了,举个例子:当最小的ai等于1时,那么自然区间内的所有数都可以凑出来了。
  10. */
  1. /*网上的AC代码,我加了注解,注意把I64d改为lld*/
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<algorithm>
  6. #include<cmath>
  7.  
  8. #define md
  9. #define ll long long
  10. #define inf 1000000000000000LL
  11. #define eps 1e-8
  12. #define N 500010
  13. using namespace std;
  14. int q[N];
  15. ll dis[N];
  16. bool vis[N];
  17. int mn,n;
  18. int a[];
  19. void spfa()
  20. {
  21. int h=,w=,x,y; q[]=; vis[]=;/*第一个能凑出的数就是0*/
  22. while (h!=w)
  23. {
  24. h++; if (h>mn+) h=; x=q[h];/*循环队列,取出队头的数*/
  25. for (int i=;i<=n;i++)
  26. {
  27. y=(x+a[i])%mn;/*利用这个价值和其他价值组合所能达到的y,计算y的最小花费(因为只有计算最小花费),才能用mn凑出更多的满足区间条件的数*/
  28. if (dis[y]>dis[x]+a[i])
  29. {
  30. dis[y]=dis[x]+a[i];
  31. if (!vis[y])
  32. {
  33. vis[y]=;
  34. w++; if (w>mn+) w=; q[w]=y;
  35. }
  36. }
  37. }
  38. vis[x]=;
  39. }
  40. }
  41.  
  42. ll query(ll x)
  43. {
  44. ll ans=;
  45. for (int i=;i<mn;i++)
  46. if (dis[i]<=x) ans+=(x-dis[i])/mn+; /*计算有多少个k满足k*mn+i<=x,因为k>=0,所以还要加1*/
  47. return ans;
  48. }
  49.  
  50. /*windows 用I64d linux 用lld*/
  51. int main()
  52. {
  53. mn=(1e9);
  54. ll L,R;
  55. scanf("%d%I64d%I64d",&n,&L,&R);
  56. for (int i=;i<=n;i++) { scanf("%d",&a[i]); if (a[i]==) { i--; n--; continue;} mn=min(mn,a[i]);}/*取出最小的an,但是不能为0,很好理解吧*/
  57. for (int i=;i<mn;i++) dis[i]=inf;/*设达到每个k*mn+i(i<mn)的最小花费,所以数组dis中只有小于mn的i即可(*/
  58. spfa();
  59. printf("%I64d\n",query(R)-query(L-));
  60. return ;
  61. }
  1. /*
  2. 首先,答案=ans(Bmax)-ans(Bmin-1)//利用差分
  3. 找出a1到an中的最小值p,则如果可以构造出答案x,就可以构造出答案x+p
  4. 所以我们只需要对于每个q(0<=q<p),计算出最小的k,使k*p+q能够能够被构造出来,那么对于k’(k’>k) k’*p+q也能构造出来
  5. 所以对于每个q建一个点,对于每个ai,从q向(q+ai)%p连一条长度为ai的边,先跑一遍最短路,计算出得到每个q的最小花费,如果最小花费大于了Bmax,那么没有办法凑出了。否则就计算可以凑出多少个。
  6.  
  7. */
  8. #define N 15
  9. #define S 500010 //注意题目时5*1e5
  10. #include<iostream>
  11. using namespace std;
  12. #include<cstdio>
  13. #include<queue>
  14. typedef long long ll;
  15. ll L,R;
  16. bool vis[S]={};
  17. int n,mn=(<<)-,a[N];
  18. ll dis[S];
  19. void input()
  20. {
  21. cin>>n>>L>>R;
  22. for(int i=;i<=n;++i)
  23. {
  24. scanf("%d",&a[i]);
  25. if(a[i]==)
  26. {
  27. i--;n--;
  28. continue;
  29. }
  30. mn=min(mn,a[i]);
  31. }
  32. }
  33. void spfa()
  34. {
  35. queue<int>Q;
  36. Q.push();
  37. vis[]=true;
  38. dis[]=;/*注意得到0的花费是0*/
  39. int x,y;
  40. while(!Q.empty())
  41. {
  42. x=Q.front();Q.pop();
  43. vis[x]=false;
  44. for(int i=;i<=n;++i)
  45. {
  46. y=(x+a[i])%mn;
  47. if(dis[y]>dis[x]+a[i])
  48. {
  49. dis[y]=dis[x]+a[i];
  50. if(!vis[y])
  51. {
  52. vis[y]=true;
  53. Q.push(y);
  54. }
  55. }
  56. }
  57. }
  58. }
  59. ll query(ll x)
  60. {
  61. ll ans=;
  62. for(int i=;i<mn;++i)/*别忘了从0开始循环,因为凑出的是0,可以全部用mn来凑*/
  63. if(dis[i]<=x) ans+=(x-dis[i])/mn+;
  64. return ans;
  65. }
  66. int main()
  67. {
  68. input();
  69. for(int i=;i<mn;++i)
  70. dis[i]=100000000000000000LL;//当赋值longlong的数时,要加后缀ll(大小写都可以)才可以,否则会出错的。
  71. spfa();
  72. cout<<query(R)-query(L-);
  73. return ;
  74. }

数论+spfa算法 bzoj 2118 墨墨的等式的更多相关文章

  1. 【BZOJ 2118】 墨墨的等式(Dijkstra)

    BZOJ2118 墨墨的等式 题链:http://www.lydsy.com/JudgeOnline/problem.php?id=2118 Description 墨墨突然对等式很感兴趣,他正在研究 ...

  2. 【BZOJ 2118】墨墨的等式

    http://www.lydsy.com/JudgeOnline/problem.php?id=2118 最短路就是为了找到最小的$x$满足$x=k×a_{min}+d,0≤d<a_{min}$ ...

  3. bzoj 2118: 墨墨的等式 spfa

    题目: 墨墨突然对等式很感兴趣,他正在研究\(a_1x_1+a_2y_2+ ... +a_nx_n=B\)存在非负整数解的条件,他要求你编写一个程序,给定\(N,\{a_n\}\)以及\(B\)的取值 ...

  4. bzoj 2118 墨墨的等式 - 图论最短路建模

    墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input ...

  5. 【BZOJ 2118】 2118: 墨墨的等式 (最短路)

    2118: 墨墨的等式 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求 ...

  6. bzoj 2118: 墨墨的等式

    Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在 ...

  7. [图论训练]BZOJ 2118: 墨墨的等式 【最短路】

    Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在 ...

  8. BZOJ2118墨墨的等式[数论 最短路建模]

    2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1317  Solved: 504[Submit][Status][Discus ...

  9. BZOJ2118: 墨墨的等式(最短路 数论)

    题意 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. So ...

随机推荐

  1. mysql并发insert deadlock分析以及解决,无delete/update/for update

    关于并发insert操作发生deadlock这个情况,一直有很多争议,而且网上的帖子所有的例证和模拟其实不一定反映了真实的情况,例如:https://www.percona.com/blog/2012 ...

  2. 生理周期(c++实现)

    描述:人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23 天. 28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如,智力周期的高峰,人会思维 ...

  3. Vue混合

    gitHub地址: https://github.com/lily1010/vue_learn/tree/master/lesson13 一 定位 混合以一种灵活的方式为组件提供分布复用功能.混合对象 ...

  4. 使用Reflexil修改类库

    因为公司一个项目需要修改PPS的颜色,于是反编译了PPS的代码发现,作者很不厚道的把所有着色都HardCode在代码里 private static void InsertDefaultSeriesC ...

  5. 转:【前端福利】用grunt搭建自动化的web前端开发环境-完整教程

    原文地址:http://blog.csdn.net/wangfupeng1988/article/details/46418203 jQuery在使用grunt,bootstrap在使用grunt,百 ...

  6. SqlServer int型转varchar型 出现*号

    今天调一个bug,错误提示执行语句 * 附近有语法错误,看了存储过程半天没啥反应,我就更本没有* .打印了一下语句发现 where Mor_Id=* 仔细一看set @sqlupdate+=' whe ...

  7. iOS之UI--涂鸦画板实例 (有待更新)

    首先是搭建框架 其他的略过,直接展示效果: 然后接下来上传搭建好两个控制器框架的源码百度云下载链接: http://pan.baidu.com/s/1skjpDox 密码: ardx ,工程里面还有我 ...

  8. 解决win2003/2008下注册机或破解补丁程序无法运行问题

    win Server 2003/2008 64位系统均遇到注册机或破解补丁程序无法运行或报错或死机的情况,原因是win系统默认开启了文件数据执行保护导致的. (比如3DMax的破解补丁程序等...) ...

  9. Java 读取指定目录下的文件名和目录名

    需求:读取指定目录下的文件名和目录名 实现如下: package com.test.common.util; import java.io.File; public class ReadFile { ...

  10. tair源码分析——leveldb存储引擎使用

    分析完leveldb以后,接下来的时间准备队tair的源码进行阅读和分析.我们刚刚分析完了leveldb而在tair中leveldb是其几大存储引擎之一,所以我们这里首先从tair对leveldb的使 ...