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。

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

数论+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. socket调用流程的函数及数据结构

    如有错误,欢迎指正. 如果需要,可以提供visio原文件. 参考: 1. <追踪Linux TCPIP代码运行--基于2.6内核> 2. Linux Kernel 2.6.26

  2. u-boot移植总结(二)LED点灯调试 和 u-boot加载地址

    (一)LED点灯调试 FL2440电路总共有4个LED0,LED1,LED2,LED3,分别接到板子GPB5,GPB6,GPB8,GPB10引脚.通过设置三个寄存器GPBCON(0x56000010) ...

  3. POJ 1836 Alignment 最长递增子序列(LIS)的变形

    大致题意:给出一队士兵的身高,一开始不是按身高排序的.要求最少的人出列,使原序列的士兵的身高先递增后递减. 求递增和递减不难想到递增子序列,要求最少的人出列,也就是原队列的人要最多. 1 2 3 4 ...

  4. PHP生成图片验证码demo【OOP面向对象版本】

    下面是我今天下午用PHP写的一个生成图片验证码demo,仅供参考. 这个demo总共分为4个文件,具体代码如下: 1.code.html中的代码: <!doctype html> < ...

  5. mysql 5.6.33发布

    2016-09-06,mysql 5.6.33社区版发布,修复的bug越发减少,而且基本上都是较少使用的特性.

  6. Webform(内置对象-Response与Redirect、QueryString传值、Repeater删改)

    一.内置对象(一)Response - 响应请求对象1.定义:Response对象用于动态响应客户端请示,控制发送给用户的信息,并将动态生成响应.Response对象只提供了一个数据集合cookie, ...

  7. 新技能,利用Reflector来修改dll引用

    继上次<ArcObject10.1降级至10.0>又遇到版本降级问题.通常的方式有: 方案一:重新编译 将源代码加载到解决方案中,修改相应dll的版本,比较快捷的方式是多选后,设置属性中特 ...

  8. SharePoint 服务器端对象模型操作用户组(创建/添加/删除)

    摘要:几个操作SharePoint用户组的方法,已经测试通过,但是没有提升权限,如果没有权限的人操作,需要提升权限(提权代码附后).大家需要的话,可以参考下,写在这里也给自己留个备份~~ //创建用户 ...

  9. 同步推是如何给未越狱的IOS设备安装任意IPA的?

    工作准备: 1. 准备一台MAC 2. 拥有一份299企业证书, 然后按照下面步骤操作: 1. 把xxxx.ipa改成xxx.zip, 解压缩得到Payload文件夹 2. 替换Payload里的em ...

  10. Struts2(十六)Json

    一.JSON Json就是浏览器和服务器之间交换数据的一种轻量级对象 javaSctipt中类似的对象操作 $(function() { var person = { "name" ...