http://www.lydsy.com/JudgeOnline/problem.php?id=2118 (Topic link)
Test instructions
Given the value range of B [Bmin,bmax], the equation a1x1+a2x2+...+anxn=b how many b can make the equation existence nonnegative integer solution.
Solution
The problem is easily translated into: using a1,a2,a3, How many of an can comprise a number within the range [Bmin,bmax]. This is a kind of classical graph theory problem.
We assume that the smallest element in a[] is T, which can be considered as the number of n can be composed of several pairs of t modulo case. A number q consisting of dis[i], and Q mod t=i,q is the minimum value that satisfies the above two conditions. We are here to change the scope of the topic to a specific inquiry, better discussion, for query x, set x mod t=i, there are the following three situations:
- Dis[i]>x. Since a modulo t consisting of the n number is the number of I, the minimum value of this number is dis[i], and dis[i]>x, which indicates that x cannot be formed.
- Dis[i]=x. Since a modulus t consisting of this n is the number of I, the minimum value of this number is dis[i], and dis[i]=x, which indicates that X can be constituted and is the smallest number of modulus t equal to I.
- Dis[i]<x. Because a mod t that is smaller than x with this number of n is the number Q of I, then x mod t=q mod T, and X must be obtained by Q plus several T, so X can also be formed.
From the above three points, when dis[i]<=x, X can be constituted, otherwise it cannot.
Now the question is how to solve the dis array?
I believe you crossing have found that the name of the dis array is a bit strange, correct is to use the shortest solution. Because the dis[i] mod t=i,i is within the range of 0~t-1, the T-point 0,1,2,,t-1 can be established. For point I and any number of a[j], set k= (I+a[j]) mod T, can be considered from I to k with the edge of the edge of A[j], indicating that the point can be t=i from the MoD, by adding edge right a[j], to the point of the MoD t=k. Since T mod t=0, you can set T to a point with a number 0. If x is required to be a number of n, the minimum value of Dis[x mod T] is required, and when x is greater than or equal to dis[x mod T], it can be composed of n number, set x mod t=j,dis[j] that is J this shop to reach 0 points of the shortest distance, it can be 0 points directly plus edge A[j] Get , and can also be reached through other intermediate points. After the conversion, it is a short-circuit problem.
Back to the question. So we first build a diagram, run the shortest way, preprocess the dis array, and then enumerate i=0~t-1, calculate the number of modulo T as I in the interval [Bmin,bmax] How many, statistical answer can be.
Details
Inside the heap again forgot to open long long, embarrassed.
Code
bzoj2118#include<algorithm> #include <iostream> #include <cstdlib> #include <cstring># include<cstdio> #include <cmath> #include <queue> #define LL long long#define MOD 10007#define inf (1ll <<60) #define Pi ACOs ( -1.0) #define FREE (a) freopen (a ".", "R", stdin), Freopen (a ". Out", "w", stdout); using namespace Std;const int maxn=500010;struct edge {int to,next,w;} E[maxn*10];struct Data {LL num,w;friend bool operator < (const data A,const data b) {return a.w>b.w;}}; int Head[maxn],a[maxn],vis[maxn];int n,cnt; LL l,dis[maxn],r;void Link (int u,int v,int W) {e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;} void Dijkstra () {priority_queue<data> q;for (int i=0;i<a[1];i++) Dis[i]=inf;data x= (data) {0,0},y;dis[0]=0; Q.push (x); while (!q.empty ()) {x=q.top (); Q.pop (); if (Vis[x.num]) continue;vis[x.num]=1;for (int i=head[x.num];i;i=e[i ].next) if (DIS[E[I].TO]>X.W+E[I].W) {Y.w=dis[e[i].to]=x.w+e[i].w;y.num=e[i].to;q.push (y);}}} int main () {scanf ("%d%Lld%lld ", &n,&l,&r); for (int i=1;i<=n;i++) scanf ("%d ", &a[i]); sort (a+1,a+1+n); if (!a[n]) return printf ("0"), 0;for (int i=0;i<a[1];i++) for (int j=2;j<=n;j++) Link (i, (a[j]+i)%a[1],a[j]);D Ijkstra (); ll ans=0;for (int i=0;i<a[1];i++) if (dis[i]<=r) {LL L=max (0LL, (L-dis[i])/a[1]); if (l*a[1]+dis[i]<l) l++; LL r= (R-dis[i])/a[1];if (r*a[1]+dis[i]>r) r--;ans+=r-l+1;} printf ("%lld\n", ans); return 0;}
The equation of "bzoj2118" ink Ink