直接放学长的讲解还有代码算了.....
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<cmath> #include<stack> #include<algorithm> #define rg register #define ll long long #define LDB long double #define ull unsigned long long #define view(i,x) for(rg int i=hd[x];i!=-1;i=e[i].nt) #define go(i,x,a) for(rg int i=a;i<x;i++) #define inf 0x3f3f3f3f #define INF 0x7fffffff using namespace std; const int maxn=5e5+5; int n,hd[maxn],k,a[maxn],vis[maxn]; ll L,R,dis[maxn]; struct edd{ int nt,v,w; }e[maxn*20]; inline ll rd(){ ll ret=0,af=1; char gc=getchar(); while(gc < '0' || gc > '9'){ if(gc=='-') af=-af; gc=getchar(); } while(gc >= '0' && gc <= '9') ret=ret*10+gc-'0',gc=getchar(); return ret*af; } inline void add(int a,int b,int c){ e[k].v=b; e[k].w=c; e[k].nt=hd[a]; hd[a]=k++; } void spfa(){ memset(dis,-1,sizeof(dis)); deque<int>q; /*go(i,n+1,1){ int x=a[i]%a[1]; if(dis[x] == -1) dis[x]=a[i],q.push_back(x),vis[x]=1; else dis[x]=min(dis[x],(ll)a[i]); }*/ q.push_back(0); vis[0]=1; dis[0]=0; while(!q.empty()){ int x=q.front(); q.pop_front(); vis[x]=0; for(rg int i=hd[x];i!=-1;i=e[i].nt){ int v=e[i].v,w=e[i].w; if(dis[v] == -1 || dis[v] > dis[x]+w){ dis[v]=dis[x]+w; if(!vis[v]){ if(q.empty()) q.push_back(v); else if(dis[v] < dis[q.front()]) q.push_front(v); else q.push_back(v); vis[v]=1; } } } } } inline ll cal(ll m){ ll ans=0; go(i,a[1],0){ if(dis[i] > m || dis[i] == -1) continue; ans=ans+(m-dis[i])/a[1]+1; } return ans; } int main(){ #ifndef ONLINE_JUDGE freopen("3.in","r",stdin); //freopen(".out","w",stdout); #endif memset(hd,-1,sizeof(hd)); k=0; n=rd(); L=rd(); R=rd(); go(i,n+1,1) a[i]=rd(); sort(a+1,a+n+1); go(i,a[1],0) go(j,n+1,2) add(i,(i+a[j])%a[1],a[j]); spfa(); printf("%lld",cal(R)-cal(L-1)); return 0; }//Faze