bzoj 2118: 墨墨的等式 spfa
2017-03-20 06:10
435 查看
题目:
墨墨突然对等式很感兴趣,他正在研究\(a_1x_1+a_2y_2+ ... +a_nx_n=B\)存在非负整数解的条件,他要求你编写一个程序,给定\(N,\{a_n\}\)以及\(B\)的取值范围,求出有多少\(B\)可以使等式存在非负整数解。
题解:
首先我们发现 : 如果我们能够通过选取一些数凑到\(x\),那么我们肯定能够凑到$x + a_1 ,x + 2a_1 ,x + 3a_1, ... $
所以我们考虑在\(mod a_1\)的剩余系下进行操作.
记\(f[x]\)表示取到可以用\(k*a_1 + x\)表示的数的最小的\(k\)
这个dp我们可以直接利用最短路算法求解.
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; inline void read(ll &x){ x=0;char ch;bool flag = false; while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true; while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x; } const ll maxn = 500500; const ll lim = maxn<<1; ll a[maxn],dis[maxn],q[lim + 10],l,r,n; bool inq[maxn]; void spfa(){ memset(dis,0x3f,sizeof dis); l = 0;r = -1; dis[0] = 0;q[++r] = 0; inq[0] = true; while(l <= r){ ll u = q[l++]; for(ll i=2;i<=n;++i){ ll v = (u + a[i]) % a[1]; if( dis[v] > dis[u] + (u+a[i])/a[1]){ dis[v] = dis[u] + (u+a[i])/a[1]; if(!inq[v]){ q[++r] = v; inq[v] = true; } } }inq[u] = false; } } inline ll calc(ll x){ ll ret = 0; for(ll i=0;i<a[1];++i){ ret += max((x/a[1] + ((x % a[1]) >= i)) - dis[i],0LL); }return ret; } int main(){ ll L,R;read(n);read(L);read(R); ll pos = 0; for(ll i=1;i<=n;++i){ read(a[i]); if(pos == 0 || a[pos] > a[i]) pos = i; }swap(a[pos],a[1]); if(a[1] == 0) return puts("0"); spfa(); printf("%lld\n",calc(R) - calc(L-1)); getchar();getchar(); return 0; }
相关文章推荐
- bzoj 2118 墨墨的等式 - 图论最短路建模
- BZOJ 2118 墨墨的等式 最短路 同余类分析
- BZOJ2118 墨墨的等式
- [BZOJ2118] 墨墨的等式(最短路)
- 【BZOJ2118】墨墨的等式
- 【bzoj2118】墨墨的等式
- bzoj2118 墨墨的等式
- 【BZOJ2118】墨墨的等式(dijkstra)
- bzoj 2118: 墨墨的等式
- BZOJ 2118: 墨墨的等式
- Bzoj2118 墨墨的等式
- BZOJ 2118 墨墨的等式
- BZOJ2118墨墨的等式[数论 最短路建模]
- BZOJ2118 墨墨的等式
- 【bzoj2118】 墨墨的等式
- BZOJ_2118_墨墨的等式_最短路
- BZOJ2118: 墨墨的等式
- BZOJ 2118 墨墨的等式[Waiting]
- bzoj 2118: 墨墨的等式 最短路建模
- bzoj2118 墨墨的等式 最短路