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

 /**
* bzoj
* Problem#2118
* Accepted
* Time:2888ms
* Memory:93712k
*/
#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<ctime>
#include<map>
#include<stack>
#include<set>
#include<queue>
#include<vector>
#ifndef WIN32
#define AUTO "%lld"
#else
#define AUTO "%I64d"
#endif
using namespace std;
typedef bool boolean;
#define inf 0xfffffff
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline boolean readInteger(T& u) {
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-') {
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
u *= aFlag;
ungetc(x, stdin);
return true;
} ///map template starts
typedef class Edge{
public:
int end;
int next;
int w;
Edge(const int end = , const int next = , const int w = ):end(end), next(next), w(w) { }
}Edge; typedef class MapManager{
public:
int ce;
int *h;
Edge *edge;
MapManager() { }
MapManager(int points, int limit):ce() {
h = new int[(const int)(points + )];
edge = new Edge[(const int)(limit + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end, int w) {
edge[++ce] = Edge(end, h[from], w);
h[from] = ce;
}
Edge& operator [] (int pos) {
return edge[pos];
}
}MapManager;
#define m_begin(g, i) (g).h[(i)]
///map template ends int n;
long long bmin, bmax;
MapManager g;
int* a;
int moder = inf; inline void init() {
readInteger(n);
readInteger(bmin);
readInteger(bmax);
a = new int[(const int)(n + )];
for(int i = ; i <= n; i++) {
readInteger(a[i]);
if(a[i] == ) {
i--, n--;
continue;
}
smin(moder, a[i]);
}
} boolean *visited;
long long* dis;
queue<int> que;
inline void spfa(int s) {
visited = new boolean[(const int)(moder)];
dis = new long long[(const int)(moder)];
memset(visited, false, sizeof(boolean) * (moder));
memset(dis, 0x7f, sizeof(long long) * (moder));
dis[s] = ;
que.push(s);
while(!que.empty()) {
int e = que.front();
que.pop();
visited[e] = false;
for(int i = m_begin(g, e); i != ; i = g[i].next) {
int &eu = g[i].end;
if(dis[e] + g[i].w < dis[eu]) {
dis[eu] = dis[e] + g[i].w;
if(!visited[eu]) {
que.push(eu);
visited[eu] = true;
}
}
}
}
} inline long long calc(long long x) {
long long ret = ;
for(int i = ; i < moder; i++) {
if(dis[i] <= x)
ret += (x - dis[i]) / (long long)moder + ;
}
return ret;
} inline void solve() {
g = MapManager(moder, moder * n * );
for(int i = ; i < moder; i++) {
for(int j = ; j <= n; j++) {
if(a[j] == moder) continue;
g.addEdge(i, (i + a[j]) % moder, a[j]);
}
}
spfa();
long long res = calc(bmax) - calc(bmin - );
printf(AUTO, res);
} int main() {
init();
solve();
return ;
}

bzoj 2118 墨墨的等式 - 图论最短路建模的更多相关文章

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

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

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

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

  3. 【BZOJ 2118】墨墨的等式

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

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

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

  5. 数论+spfa算法 bzoj 2118 墨墨的等式

    2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1283  Solved: 496 Description 墨墨突然对等式很感兴 ...

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

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

  7. bzoj 2118: 墨墨的等式

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

  8. bzoj 2118: 墨墨的等式 spfa

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

  9. 【BZOJ2118】墨墨的等式(最短路)

    [BZOJ2118]墨墨的等式(最短路) 题面 BZOJ 洛谷 题解 和跳楼机那题是一样的. 只不过走的方式从\(3\)种变成了\(n\)种而已,其他的根本没有区别了. #include<ios ...

随机推荐

  1. 【紫书】Rails UVA - 514 栈

    题意:判断出栈顺序是否合法 题解:两个指针,A指向入栈序列,B指向出栈. 的分三种情况:if     1.A==B :直接入栈加出栈即可A++,B++ else 2.和栈顶相同,直接出栈A==stac ...

  2. POJ - 1101 The Game dfs

    题意:给你一个地图,上面有一些‘X',给你起点终点,让你输出从起点到终点的路径中转向(改变方向)次数最少的路径,注意,不能穿过别的’X'并且可以超过边界 题解:关于超过边界,只要在外围多加一圈‘ ’. ...

  3. iOS 项目架构tabbarController 嵌套 navbarController

    简单思路: 进入APP,首先加载 splashVC,加载完成之后,在viewDidAppear里跳转到loginVC,(这里一定要在viewDidLoad方法里新建loginVC跳转). 登陆成功之后 ...

  4. The History of Operating Systems

    COMPPUTER SCIENCE AN OVERVIEW 11th Edition job 作业 batch processing 批处理 queue 队列 job queue 作业队列 first ...

  5. Web终端SSH功能

    http://www.laozuo.org/10703.html------ CentOS安装配置GateOne实现Web终端SSH功能

  6. Spark-Cache与Checkpoint

    一.Cache缓存操作 scala> val rdd1 = sc.textFile("hdfs://192.168.146.111:9000/logs") rdd1: org ...

  7. oracle(十)临时表

    1.临时表的特点 (1)多用户操作的独立性:对于使用同一张临时表的不同用户,oracle都会分配一个独立的 Temp Segment,这样就避免了多个用户在对同一张临时表操作时 发生交叉,从而保证了多 ...

  8. A solution for MySQL Assertion failure FIL_NULL

    A solution for MySQL Assertion failure FIL_NULL http://michaelfranzl.com/2014/01/25/solution-mysql-a ...

  9. python 的 json 转换

    python 的 json 转换 本文为原创文章,禁止转载! 本文以 json.dumps()  和 json.loads() 方法进行 Python 数据和 json 格式之间转换,进行讲解 首先比 ...

  10. 【转】Linux进程绑CPU核

    1. 什么是绑核? 所谓绑核,其实就是设定某个进程/线程与某个CPU核的亲和力(affinity).设定以后,Linux调度器就会让这个进程/线程只在所绑定的核上面去运行.但并不是说该进程/线程就独占 ...