题目传送门:bzoj2118 洛谷P2371

  这道题看了题解后才会的。。果然是国家集训队的神仙题,思维独特。

  首先若方程$ \sum_{i=1}^{n}a_ix_i=k $有非负整数解,那么显然对于每一个$ a_i $方程$ \sum_{i=1}^{n}a_ix_i=k $都必有非负整数解。于是若取$ Min=\min(a_i) $,那么对于任意$ j \in [0,min) $,若对于自然数数$ k $,$ \sum_{i=1}^{n}a_ix_i=k (k \equiv j (mod \ Min)) $有解,则对于一切自然数$ B>k(B \equiv j (mod \ Min)) $,方程$ \sum_{i=1}^{n}a_ix_i=k $都必有解。因此,我们只需对每一个$ j $求出对应的$ k $值。(我代码中实际求的是$ k/Min $,取$ Min $是为了让状态数尽可能小)

  但是,这个值怎么求呢?根据上文,若$ \sum_{i=1}^{n}a_ix_i=k $,则我们可以尝试将$ k $分别加上每一个$ a_i $得到新的合法数值。这其实相当于对于每一个$ i \in [1,n] $,从$ k $向$ (k+a_i)mod \ Min $连一条长度为$ a_i $的边。同时,我们要使$ k $尽可能小,所以要在原图中跑最短路求解。

  代码:

  dijkstra+堆(这个如果dijkstra写得不好在洛谷上会tle)

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<ctime>
  6. #include<algorithm>
  7. #include<queue>
  8. #include<vector>
  9. #include<map>
  10. #define ll long long
  11. #define ull unsigned long long
  12. #define max(a,b) (a>b?a:b)
  13. #define min(a,b) (a<b?a:b)
  14. #define lowbit(x) (x& -x)
  15. #define mod 1000000000
  16. #define inf 0x3f3f3f3f
  17. #define eps 1e-18
  18. #define maxn 5010
  19. inline ll read(){ll tmp=; char c=getchar(),f=; for(;c<''||''<c;c=getchar())if(c=='-')f=-; for(;''<=c&&c<='';c=getchar())tmp=(tmp<<)+(tmp<<)+c-''; return tmp*f;}
  20. inline ll power(ll a,ll b){ll ans=; for(;b;b>>=){if(b&)ans=ans*a%mod; a=a*a%mod;} return ans;}
  21. inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
  22. inline void swap(int &a,int &b){int tmp=a; a=b; b=tmp;}
  23. struct data{
  24. int id,dis;
  25. friend bool operator < (data a,data b){
  26. return a.dis>b.dis;
  27. }
  28. };
  29. std::priority_queue<data>heap;
  30. struct edge{
  31. int to,nxt,d;
  32. }e[];
  33. int fir[],mark[],dist[];
  34. int a[];
  35. int n,m,tot=;
  36. ll l,r;
  37. void add(int x,int y,int z){e[tot].to=y; e[tot].d=z; e[tot].nxt=fir[x]; fir[x]=tot++;}
  38. void dij(int S)
  39. {
  40. memset(dist,0x3f,sizeof(dist));
  41. memset(mark,,sizeof(mark));
  42. data now; now.id=S; now.dis=; heap.push(now);
  43. while(!heap.empty()){
  44. now=heap.top(); heap.pop();
  45. if(mark[now.id])continue;
  46. mark[now.id]=; dist[now.id]=now.dis;
  47. for(int i=fir[now.id];~i;i=e[i].nxt)
  48. if(!mark[e[i].to]){
  49. data tmp; tmp.id=e[i].to; tmp.dis=dist[now.id]+e[i].d;
  50. heap.push(tmp);
  51. }
  52. // printf("A\n");
  53. }
  54. }
  55. int main()
  56. {
  57. memset(fir,,sizeof(fir));
  58. n=read(); l=read(); r=read();
  59. int mn=inf;
  60. for(int i=;i<=n;i++)
  61. a[i]=read(),mn=min(mn,a[i]);
  62. for(int i=;i<mn;i++)
  63. for(int j=;j<=n;j++){
  64. int nxt=i+a[j];
  65. add(i,nxt%mn,nxt/mn);
  66. }
  67. dij();
  68. // for(int i=0;i<mn;i++)printf("%d %d\n",i,dist[i]);
  69. ll ans=;
  70. for(int i=;i<mn;i++)
  71. if(1ll*dist[i]*mn+i<=r){
  72. ll L=max(dist[i]*mn+i,l),R=r;
  73. if(L/mn<R/mn){
  74. ans+=R/mn-L/mn-;
  75. if(L<=L/mn*mn+i&&L/mn*mn+i<=R)++ans;
  76. if(L<=R/mn*mn+i&&R/mn*mn+i<=R)++ans;
  77. }
  78. else if(L<=L/mn*mn+i&&L/mn*mn+i<=R)++ans;
  79. // printf("*** %d %lld %lld %lld\n",i,ans,L,R);
  80. }
  81. printf("%lld\n",ans);
  82. }

bzoj2118&&洛谷P2371

  spfa(这个就很清真了,跑得飞快)

  1. #include<cstdio>
  2. #include<cmath>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<ctime>
  6. #include<algorithm>
  7. #include<queue>
  8. #include<vector>
  9. #include<map>
  10. #define ll long long
  11. #define ull unsigned long long
  12. #define max(a,b) (a>b?a:b)
  13. #define min(a,b) (a<b?a:b)
  14. #define lowbit(x) (x& -x)
  15. #define mod 1000000000
  16. #define inf 0x3f3f3f3f
  17. #define eps 1e-18
  18. #define maxn 5010
  19. inline ll read(){ll tmp=; char c=getchar(),f=; for(;c<''||''<c;c=getchar())if(c=='-')f=-; for(;''<=c&&c<='';c=getchar())tmp=(tmp<<)+(tmp<<)+c-''; return tmp*f;}
  20. inline ll power(ll a,ll b){ll ans=; for(;b;b>>=){if(b&)ans=ans*a%mod; a=a*a%mod;} return ans;}
  21. inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
  22. inline void swap(int &a,int &b){int tmp=a; a=b; b=tmp;}
  23. using namespace std;
  24. struct edge{
  25. int to,nxt,d;
  26. }e[];
  27. int fir[],inq[],dist[];
  28. int q[];
  29. int a[];
  30. int n,m,tot=;
  31. ll l,r;
  32. void add(int x,int y,int z){e[tot].to=y; e[tot].d=z; e[tot].nxt=fir[x]; fir[x]=tot++;}
  33. void spfa(int S)
  34. {
  35. memset(dist,0x3f,sizeof(dist));
  36. memset(inq,,sizeof(inq));
  37. int h=,t=; q[]=S; inq[S]=; dist[S]=;
  38. while(h<=t){
  39. for(int i=fir[q[h]];~i;i=e[i].nxt)
  40. if(dist[q[h]]+e[i].d<dist[e[i].to]){
  41. dist[e[i].to]=dist[q[h]]+e[i].d;
  42. if(!inq[e[i].to]){
  43. q[++t]=e[i].to; inq[e[i].to]=;
  44. }
  45. }
  46. inq[q[h++]]=;
  47. }
  48. }
  49. int main()
  50. {
  51. memset(fir,,sizeof(fir));
  52. n=read(); l=read(); r=read();
  53. int mn=inf;
  54. for(int i=;i<=n;i++)
  55. a[i]=read(),mn=min(mn,a[i]);
  56. for(int i=;i<mn;i++)
  57. for(int j=;j<=n;j++){
  58. int nxt=i+a[j];
  59. add(i,nxt%mn,nxt/mn);
  60. }
  61. spfa();
  62. ll ans=;
  63. for(int i=;i<mn;i++)
  64. if(1ll*dist[i]*mn+i<=r){
  65. ll L=max(dist[i]*mn+i,l),R=r;
  66. if(L/mn<R/mn){
  67. ans+=R/mn-L/mn-;
  68. if(L<=L/mn*mn+i&&L/mn*mn+i<=R)++ans;
  69. if(L<=R/mn*mn+i&&R/mn*mn+i<=R)++ans;
  70. }
  71. else if(L<=L/mn*mn+i&&L/mn*mn+i<=R)++ans;
  72. }
  73. printf("%lld\n",ans);
  74. }

bzoj2118&&洛谷P2371

【bzoj2118&洛谷P2371】墨墨的等式(最短路神仙题)的更多相关文章

  1. 洛谷P1067 多项式输出 NOIP 2009 普及组 第一题

    洛谷P1067 多项式输出 NOIP 2009 普及组 第一题 题目描述 一元n次多项式可用如下的表达式表示: 输入输出格式 输入格式 输入共有 2 行 第一行 1 个整数,n,表示一元多项式的次数. ...

  2. 洛谷P2371 [国家集训队]墨墨的等式

    P2371 [国家集训队]墨墨的等式 题目描述 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=Ba_1x_1+a_2y_2+-+a_nx_n=Ba1​x1​+a2​y2​+-+a ...

  3. 洛谷 P5304 [GXOI/GZOI2019]旅行者(最短路)

    洛谷:传送门 bzoj:传送门 参考资料: [1]:https://xht37.blog.luogu.org/p5304-gxoigzoi2019-lv-xing-zhe [2]:http://www ...

  4. 【BZOJ2763/洛谷p4563】【分层图最短路】飞行路线

    2763: [JLOI2011]飞行路线 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 4630  Solved: 1797[Submit][Stat ...

  5. 洛谷P1462-通往奥格瑞玛的道路-二分+最短路

    洛谷P1462-通往奥格瑞玛的道路 题目描述 在艾泽拉斯,有\(n\)个城市.编号为\(1,2,3,...,n\). 城市之间有\(m\)条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联 ...

  6. 洛谷——P2371 EXCEEDED WARNING C(50)

    P2371 EXCEEDED WARNING C 题目背景 第三道溢出警告... 机(wei)智(suo)的TMXi又搬题来坑大家了... 注意时空限制[坏笑] 题目描述 [li]1949年,阿三的数 ...

  7. 洛谷 P1876 开灯(思维,枚举,规律题)

    P1876 开灯 题目背景 该题的题目是不是感到很眼熟呢? 事实上,如果你懂的方法,该题的代码简直不能再短. 但是如果你不懂得呢?那...(自己去想) 题目描述 首先所有的灯都是关的(注意是关!),编 ...

  8. 洛谷 P2622 关灯问题II(状压DP入门题)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题解: 相关变量解释: int n,m; ];//a[i][j] : 第i个开关对第j个 ...

  9. 洛谷 p1164 小A点菜 【dp(好题)】 || 【DFS】 【恰好完全装满】

    题目链接:https://www.luogu.org/problemnew/show/P1164 题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. u ...

随机推荐

  1. SSH配置免秘钥登录

    一.  SSH 配置免秘要登录 配置SSH 免秘要登录,虽然就那么几步,但总是会出现点小问题,今天就做下记录.SSH 免秘钥就是让两台机器相互信任,不需要输入密码就能相互登录.配置相互信任就是把各自的 ...

  2. hdu 5068(线段树+矩阵乘法)

    矩阵乘法来进行所有路径的运算, 线段树来查询修改. 关键还是矩阵乘法的结合律. Harry And Math Teacher Time Limit: 5000/3000 MS (Java/Others ...

  3. 【BZOJ4849】[Neerc2016]Mole Tunnels 模拟费用流

    [BZOJ4849][Neerc2016]Mole Tunnels Description 鼹鼠们在底下开凿了n个洞,由n-1条隧道连接,对于任意的i>1,第i个洞都会和第i/2(取下整)个洞间 ...

  4. (六)通过solr7的API实现商品的列表查询

    (六)通过solr7的API实现商品的列表查询 工具类: 获取 HttpSolrClient public class Constant { public static HttpSolrClient ...

  5. mysql练手

    1.根据图创建下列表格 没有外键的表先创建,创建顺序为teacher,class,course,student CREATE TABLE class ( cid INT NOT NULL auto_i ...

  6. 常用代码块:创建httpclient 2

    HttpGet httpGet = new HttpGet(url);SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(ne ...

  7. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  8. HDU 3182 Hamburger Magi(状压dp)

    题目链接:pid=3182">http://acm.hdu.edu.cn/showproblem.php?pid=3182 Problem Description In the mys ...

  9. Android-自己定义meta-data扩展数据

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/wwj_748/article/details/25079991 Android-自己定义meta-d ...

  10. 并发 错误 java.lang.IllegalMonitorStateException: current thread not owner 分析

    public class ThreadTest implements Callable<String> { public String call() throws Exception { ...