墨墨突然对等式很感兴趣,他正在研究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。


  直接说正解,找到ai中的一个数(通常找最小的那一个,这样可以降低时间复杂度,至于为什么,看完应该就知道了),暂且设它为m吧。

  我们知道如果存在一个x,它能够被凑出来,那么(x + m), (x + 2m), ...都可以被凑出来。现在我们要找到这么一个最小的x。先建立一些点0,1,2,...,m - 1,表示满足条件的B模m的值。暂时先不考虑如何求出一次Bmin ~ Bmax中满足条件的B,因为可以用0到Bmax中的方案数减去0到Bmin - 1中的方案数。每个点连n - 1条边,第i个点的第j条边连向第(i + aj) % m个点,边权为aj

  看似有些跑题了,现在来讲讲它在题目中的含义。现在我们希望求到所有满足条件的最小的x,我们知道,当B模m的值为0时,B最小为0。同时我们可以用这个推出与它相邻的点代表的最小的B。再仔细想想,多推一下,这不是等价于求最短路吗?也就是说,从节点0出发,到达i的距离表示,最小的B模m的值为i的B的值。

  最后计算一下方案数(相信你会做)就好了。还有特殊处理当某个a等于0的时候,不然会整数被零除,然后无限RE。另外,贡献一发wa,建图注意是单向的,减个aj就不知道是不是满足了,笑。

Code

  1 /**
  2  * bzoj
  3  * Problem#2118
  4  * Accepted
  5  * Time:2888ms
  6  * Memory:93712k
  7  */
  8 #include<iostream>
  9 #include<fstream>
 10 #include<sstream>
 11 #include<algorithm>
 12 #include<cstdio>
 13 #include<cstring>
 14 #include<cstdlib>
 15 #include<cctype>
 16 #include<cmath>
 17 #include<ctime>
 18 #include<map>
 19 #include<stack>
 20 #include<set>
 21 #include<queue>
 22 #include<vector>
 23 #ifndef WIN32
 24 #define AUTO "%lld"
 25 #else
 26 #define AUTO "%I64d"
 27 #endif
 28 using namespace std;
 29 typedef bool boolean;
 30 #define inf 0xfffffff
 31 #define smin(a, b) (a) = min((a), (b))
 32 #define smax(a, b) (a) = max((a), (b))
 33 template<typename T>
 34 inline boolean readInteger(T& u) {
 35     char x;
 36     int aFlag = 1;
 37     while(!isdigit((x = getchar())) && x != '-' && x != -1);
 38     if(x == -1)    {
 39         ungetc(x, stdin);
 40         return false;
 41     }
 42     if(x == '-') {
 43         aFlag = -1;
 44         x = getchar();
 45     }
 46     for(u = x - '0'; isdigit((x = getchar())); u = u * 10 + x - '0');
 47     u *= aFlag;
 48     ungetc(x, stdin);
 49     return true;
 50 }
 51
 52 ///map template starts
 53 typedef class Edge{
 54     public:
 55         int end;
 56         int next;
 57         int w;
 58         Edge(const int end = 0, const int next = 0, const int w = 0):end(end), next(next), w(w) {    }
 59 }Edge;
 60
 61 typedef class MapManager{
 62     public:
 63         int ce;
 64         int *h;
 65         Edge *edge;
 66         MapManager() {    }
 67         MapManager(int points, int limit):ce(0) {
 68             h = new int[(const int)(points + 1)];
 69             edge = new Edge[(const int)(limit + 1)];
 70             memset(h, 0, sizeof(int) * (points + 1));
 71         }
 72         inline void addEdge(int from, int end, int w) {
 73             edge[++ce] = Edge(end, h[from], w);
 74             h[from] = ce;
 75         }
 76         Edge& operator [] (int pos) {
 77             return edge[pos];
 78         }
 79 }MapManager;
 80 #define m_begin(g, i) (g).h[(i)]
 81 ///map template ends
 82
 83 int n;
 84 long long bmin, bmax;
 85 MapManager g;
 86 int* a;
 87 int moder = inf;
 88
 89 inline void init() {
 90     readInteger(n);
 91     readInteger(bmin);
 92     readInteger(bmax);
 93     a = new int[(const int)(n + 1)];
 94     for(int i = 1; i <= n; i++) {
 95         readInteger(a[i]);
 96         if(a[i] == 0) {
 97             i--, n--;
 98             continue;
 99         }
100         smin(moder, a[i]);
101     }
102 }
103
104 boolean *visited;
105 long long* dis;
106 queue<int> que;
107 inline void spfa(int s) {
108     visited = new boolean[(const int)(moder)];
109     dis = new long long[(const int)(moder)];
110     memset(visited, false, sizeof(boolean) * (moder));
111     memset(dis, 0x7f, sizeof(long long) * (moder));
112     dis[s] = 0;
113     que.push(s);
114     while(!que.empty()) {
115         int e = que.front();
116         que.pop();
117         visited[e] = false;
118         for(int i = m_begin(g, e); i != 0; i = g[i].next) {
119             int &eu = g[i].end;
120             if(dis[e] + g[i].w < dis[eu]) {
121                 dis[eu] = dis[e] + g[i].w;
122                 if(!visited[eu]) {
123                     que.push(eu);
124                     visited[eu] = true;
125                 }
126             }
127         }
128     }
129 }
130
131 inline long long calc(long long x) {
132     long long ret = 0;
133     for(int i = 0; i < moder; i++) {
134         if(dis[i] <= x)
135             ret += (x - dis[i]) / (long long)moder + 1;
136     }
137     return ret;
138 }
139
140 inline void solve() {
141     g = MapManager(moder, moder * n * 2);
142     for(int i = 0; i < moder; i++) {
143         for(int j = 1; j <= n; j++) {
144             if(a[j] == moder) continue;
145             g.addEdge(i, (i + a[j]) % moder, a[j]);
146         }
147     }
148     spfa(0);
149     long long res = calc(bmax) - calc(bmin - 1);
150     printf(AUTO, res);
151 }
152
153 int main() {
154     init();
155     solve();
156     return 0;
157 }

转载于:https://www.cnblogs.com/yyf0309/p/6613455.html

bzoj 2118 墨墨的等式 - 图论最短路建模相关推荐

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

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

  2. BZOJ 2118: 墨墨的等式(最短路dijkstra+堆)

    2118: 墨墨的等式 Time Limit: 10 Sec Memory Limit: 259 MB Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=B存 ...

  3. p2371bzoj2118 墨墨的等式

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

  4. android 补签控件,墨墨背单词怎么补签 看完你就懂了

    现在手机的普及让不少用户在手机上面学习英语,而墨墨背单词就是一款专业的英语学习软件,它可以提醒用户每日记忆单词,还有督促你学习的签到系统,通过每日的签到不仅可以提高你学习英语的动力还能免费提升每日学习 ...

  5. 已拿字节、腾讯、墨墨 offer,音视频开发进阶指南pdf

    背了多少单词 (更慌了,随口说100个左右) 怎么知道有墨墨这个app的 (同学介绍) 你简历说你自己心思缜密,但是你简历上的句子的标点符号有问题啊.(emmm) 项目的UI问题 技术 : JavaS ...

  6. 获取墨墨背单词里面的单词书中的单词

    首先,其实是直接尝试抓包获取的,不过在抓包的信息中没发现类似的内容,然后就去百度了以下,发现还是有聪明人. 把下载的 apk 文件解压缩一下,把里面的 assets 文件夹里面的 maimemo.v3 ...

  7. 墨墨背单词刷分享链接访问量(动态获取IP代理池)

    墨墨背单词 分享链接刷点击量(自动获取最新IP代理池方式),以提高单词上限. 运行方式 1 Python 环境运行main.py 1.1 克隆本仓库 Github仓库 Momo-Share-Fresh ...

  8. app使用经验分享——墨墨背单词

    墨墨背单词 大家好,今天推荐一款干货背单词软件--墨墨背单词,相信大家对它并不陌生,它在华为应用市场上的评分是4.9,安装次数也是破1亿了. 一.设置每日学习量 点击右下角"我的" ...

  9. 墨墨背单词 无限版本

    [Android] 墨墨背单词3.8.40,9999单词上限版 https://www.52pojie.cn/thread-1300054-1-1.html

最新文章

  1. 小牛生产小牛的问题解决集粹
  2. CUDA Samples: approximate prior vbox layer
  3. Pandas进阶修炼120题,给你深度和广度的船新体验
  4. linux下防DDOS***软件及使用方法详解
  5. Haunt - Youzan 服务发现 概述
  6. 网友写的ELK安装步骤
  7. rpm 安装RabbitMQ 3.7.24版本-User can only log in via localhost
  8. Java 面试之技术框架
  9. aws s3 静态网站_使用AWS S3存储桶启动静态网站
  10. hdu 5094 Maze bfs
  11. 购物车catslider简单的多商品分类滑动
  12. (6)机器学习_支持向量机
  13. S7-1200/1500获取本地IP地址(不使用库)
  14. 异步传输模式(ATM)
  15. 基于SpringBoot的高并发秒杀(限时秒杀)
  16. NOI2009 诗人小G
  17. 面试官:你说说软件测试WHX模型(图解)
  18. 深度学习和机器博弈如何结合_对抗机器学习的博弈论方法
  19. 博弈论2-哈尔冰工业大学
  20. size = 8 * sizeof(int)是什么意思?详解代码为啥这么写?

热门文章

  1. Python爬取知网信息——Python+selenium爬取知网信息(文献名,作者,来源,发表日期,文献类型)
  2. selenium-XPATH定位
  3. 期货分仓软件的功能界面
  4. MTK NVRAM 总结
  5. UDP-疑难杂症和使用
  6. Nginx之代理详解
  7. VUE 自定义组件定义和基本使用
  8. java8 Stream流 两个list取交集,获取共有数据
  9. response.setHeader各种用法详解(转)
  10. c语言报告总结PPT,C语言程序总结.ppt