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

2118: 墨墨的等式

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1317  Solved: 504
[Submit][Status][Discuss]

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。


sdsc2016晨姐的课件:

  • 首先,答案=ans(Bmax)-ans(Bmin-1)
  • 找出a1到an中的最小值p,则如果可以构造出答案x,就可以构造出答案x+p
  • 所以我们只需要对于每个b(0<=b<p),计算出最小的k,使k*p+b能够能够被构造出来,那么对于k’(k’>k) k’*p+b也能构造出来
  • 所以对于每个b建一个点,对于每个ai,从b向(b+ai)%p连一条长度为ai的边

模p之后再建图,好厉害

注意计算答案贡献那里,/d[i]的话有蜜汁re

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
const ll N=5*1e5+5,INF=1e19;
ll n;
ll p=INF,a[20];;
ll bmx,bmn,ans=0;
struct edge{
    ll v,w,ne;
}e[N*15];
ll h[N],cnt=0;
void ins(ll u,ll v,ll w){
    cnt++;
    e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
    //cnt++;
    //e[cnt].v=u;e[cnt].w=w;e[cnt].ne=h[v];h[v]=cnt;
}
void buildGraph(){
    for(ll i=0;i<p;i++)
        for(ll j=1;j<=n;j++){
            if(a[j]==p) continue;
            ins(i,(i+a[j])%p,a[j]);
            //prllf("ins %d %lld %lld\n",i,(i+a[j])%p,a[j]);
        }
}

struct hn{
    ll u,d;
    bool operator <(const hn &rhs)const{return d>rhs.d;}
};
ll d[N];
bool done[N];
priority_queue<hn> q;
void dijkstra(ll s){
    for(ll i=0;i<p;i++) d[i]=INF;
    d[s]=0;q.push((hn){s,0});
    while(!q.empty()){
        hn x=q.top();q.pop();
        ll u=x.u;
        if(done[u]) continue;
        done[u]=1;
        for(ll i=h[u];i;i=e[i].ne){
            ll v=e[i].v;
            if(d[v]>d[u]+e[i].w){
                d[v]=d[u]+e[i].w;
                q.push((hn){v,d[v]});
            }
        }
    }
}
int main() {
    scanf("%lld%lld%lld",&n,&bmn,&bmx);
    for(ll i=1;i<=n;i++) scanf("%lld",&a[i]),p=min(p,a[i]);
    buildGraph();
    dijkstra(0);
    for(ll i=0;i<p;i++){
        if(d[i]>bmx) continue;
        ll l=max(0LL,(bmn-d[i])/p),r=(bmx-d[i])/p;
        if(l*p+d[i]<bmn) l++;
        ans+=r-l+1;
    }
    printf("%lld",ans);
    return 0;
}
时间: 2024-08-08 23:26:11

BZOJ2118墨墨的等式[数论 最短路建模]的相关文章

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

2118: 墨墨的等式 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数列的长度.B的下界.B的上界.输入的第二行包含N个整数,即数列{an}的值. Output 输出一个整数,表示有多少b可以使等式存在非负整数解. Sample Input 2 5 1

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

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1283  Solved: 496 Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数列的长度.B的下界.B的上界.输入的第二行包含N个

bzoj2118 墨墨的等式

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MB Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+-+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数列的长度.B的下界.B的上界.输入的第二行包含N个整数,即数列{an}的值. Output 输出一个

2118: 墨墨的等式

2118: 墨墨的等式 https://www.lydsy.com/JudgeOnline/problem.php?id=2118 分析: 最短路. 题意就是判断[L,R]内多少数,可以被许多个a1,a2,a3...构成.设最小的Mi = min{ai}. 直接枚举肯定超时,那么换个方法枚举. 考虑一个能构成的数b,它一定可以分解为$b = k \times M_i + r, \ r<M_i$.而且$b + M_i$也是可以构成的.所以我们可以找到最小的%Mi=r的数,比它大的%Mi=r的数可以

BZOJ 2118: 墨墨的等式

2118: 墨墨的等式 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1656  Solved: 650[Submit][Status][Discuss] Description 墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input 输入的第一行包含3个正整数,分别表示N.BMin.BMax分别表示数

[USACO14OPEN] Dueling GPS&#39;s[最短路建模]

题目描述 Farmer John has recently purchased a new car online, but in his haste he accidentally clicked the "Submit" button twice when selecting extra features for the car, and as a result the car ended up equipped with two GPS navigation systems! Ev

【bzoj2118】 墨墨的等式

http://www.lydsy.com/JudgeOnline/problem.php?id=2118 (题目链接) 题意 给出B的取值范围[Bmin,Bmax],求方程a1x1+a2x2+…+anxn=B有多少B可以使等式存在非负整数解. Solution 问题很容易就被转化为:用a1,a2,a3,······an能组成多少个在范围[Bmin,Bmax]内的数.这是一类经典的图论问题. 我们假设a[]中最小的元素为T,可以考虑用n个数能够组成的数对T的模的情况.用dis[i]表示构成的一个数

BZOJ 2118 墨墨的等式(最短路)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2118 [题目大意] 求a1x1+a2y2+…+anxn=B在B的取值范围,有多少B可以使等式存在非负整数解. [题解] 同余最短路,不等式解集计数即可. [代码] #include <cstdio> #include <algorithm> #include <queue> using namespace std; const int N=500010; n

BZOj 墨墨的等式(转化为最短路)题解

题意:中文题意不解释... 思路:这道题居然可以转化为最短路orz,要等式有非负整数解,我们可以转化一下:每个ai不限数量,问你能用ai数组拼出多少个Bmin~Bmax范围内的数,有点像完全背包的感觉,看怎样组合能拼出范围内的数. 我们找出ai中不为零的最小数记为p,如果我们把每个数进行操作ai%p ,那么所有的ai我们都可以用整数倍的p加上它的取模表示了.我们用dis[i]表示如果有一个数x:x%p == i,那么dis储存最小的x,也就是说dis储存着我们能用ai数组拼出的取模p等于i的最小