BZOJ 2118墨墨的等式
2017-02-26 09:16
183 查看
题意
墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N、{an}、以及B的取值范围,求出有多少B可以使等式存在非负整数解。
解
等式的和可以表示为B=a1*x1+B%a1,所以我们只要算出能够得到B%a1的最小的和就可以统计答案了,于是以B%a1为点向(B+ai)%a1建ai的边,跑最短路就行了。统计答案时ans=[(R-dis)-(L-1-dis)]/a1
代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<queue> #define For(i,j,k) for(int i=(j);i<=(int)k;i++) #define Forr(i,j,k) for(int i=(j);i>=(int)k;i--) #define ll long long #define Set(a,b) memset(a,b,sizeof(a)) #define pb push_back using namespace std; const int N=15,M=500010; const ll INF=(1ll<<60); ll d[M],a ,L,R,Mod=INF,ans; int n,vis[M]; inline void read(int &x){ x=0;char c=getchar();int f(0); while(c<'0'||c>'9')f|=(c=='-'),c=getchar(); while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar(); if(f)x=-x; } inline void read(ll &x){ x=0;char c=getchar();int f(0); while(c<'0'||c>'9')f|=(c=='-'),c=getchar(); while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar(); if(f)x=-x; } inline void init(){ read(n),read(L),read(R); For(i,1,n){ read(a[i]); if(a[i]==0){n--;i--;continue;} } sort(a+1,a+n+1);Mod=a[1]; For(i,1,Mod-1)d[i]=INF; d[0]=0; } inline void solve(){ queue<int>q; q.push(0);vis[0]=1; while(!q.empty()){ int r=q.front();q.pop();vis[r]=0; For(i,2,n){ ll v=(r+a[i])%Mod; if(d[v]>d[r]+a[i]){ d[v]=d[r]+a[i]; if(!vis[v]) vis[v]=1,q.push(v); } } } For(i,0,Mod-1){ if(d[i]<=R)ans=ans+(R-d[i])/Mod+1; if(d[i]<L)ans=ans-(L-1-d[i])/Mod-1; } printf("%lld\n",ans); } int main(){ init(); solve(); return 0; }
相关文章推荐
- [bzoj2118]墨墨的等式
- bzoj 2118 墨墨的等式
- BZOJ-2118 墨墨的等式(好题) 最短路+乱搞
- BZOJ2118墨墨的等式[数论 最短路建模]
- [图论训练]BZOJ 2118: 墨墨的等式 【最短路】
- BZOJ2118 墨墨的等式
- 【bzoj2118】墨墨的等式
- BZOJ 2118 墨墨的等式
- 【BZOJ2118】墨墨的等式
- 【BZOJ 2118】 墨墨的等式(Dijkstra)
- BZOJ_2118_墨墨的等式_最短路
- BZOJ 2118: 墨墨的等式
- BZOJ2118: 墨墨的等式
- bzoj 2118: 墨墨的等式 spfa
- BZOJ2118 墨墨的等式
- BZOJ 2118 墨墨的等式[Waiting]
- BZOJ 2118 墨墨的等式(最短路)
- BZOJ 2118 墨墨的等式 最短路 同余类分析
- 【BZOJ 2118】 2118: 墨墨的等式 (最短路)
- bzoj 2118: 墨墨的等式