BZOJ_P2118 墨墨的等式(最短路)

来源:互联网 发布:潘小涛 知乎 编辑:程序博客网 时间:2024/04/29 13:53

BZOJ传送门

Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 928 Solved: 356
[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。

Source

Sol:
反正我不会建模QuQ,抄题解+1
因为原等式系数不定,假定他们没有限制,考虑同余类。求出最小的a[i],如果x%a[i]=b可以得到那么x+a[i]也可以得到
最短路建模,将在mod a[i]的条件下的每个余数(其实就是[0,a[i]-1])与+每个其他数的节点连线,距离为a[j] (详细看代码吧)
最后计算方案数,求[MIN,MAX]等价于求[1,MAX]-[1,MIN]如果在%a[i]意义下最小的d[i]<=K,那么方案数就有(K-d[i])/a[i]+1,计算就可以了
QuQ我太弱了!

#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<iostream>using namespace std;#define N 500005inline long long in(long long  x=0,char ch=getchar()){while(ch>'9'||ch<'0') ch=getchar();    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}struct Edge{int to;long long v;};vector<Edge> g[N];int n,minv;long long MIN,MAX;int a[N];long long d[N];long long ans;bool b[N];struct Heap{int to;long long d;bool operator < (const Heap &a)const{return d>a.d;}};void Dijkstra(){    priority_queue<Heap> q;q.push((Heap){0,0});    memset(d,0x7f,sizeof(d));d[0]=0;int x;    while(!q.empty()){        x=q.top().to;q.pop();        if(b[x]) continue;b[x]=1;        for(int i=0,v,lim=g[x].size();i<lim;i++){            if(d[x]+g[x][i].v<d[v=g[x][i].to]){                d[v]=d[x]+g[x][i].v;                q.push((Heap){v,d[v]});            }        }    }}int main(){    n=in(),MIN=in()-1,MAX=in();minv=0x7fffffff;    for(int i=1;i<=n;i++) a[i]=in(),minv=min(minv,a[i]);    for(int i=0;i<minv;i++)        for(int j=1;j<=n;j++)             if(a[j]%minv!=0) g[i].push_back((Edge){(i+a[j])%minv,a[j]});    Dijkstra();    for(int i=0;i<minv;i++){        if(d[i]<=MIN) ans-=(MIN-d[i])/minv+1;        if(d[i]<=MAX) ans+=(MAX-d[i])/minv+1;     }    printf("%lld\n",ans);    return 0;}
0 0