题面
https://www.luogu.org/problem/P2371
题解
#include<cstdio> #include<iostream> #include<cstring> #include<vector> #include<queue> #define ri register int #define LL long long #define N 500500 using namespace std; vector<int> to[N],len[N]; LL bmax,bmin,dis[N]; bool vis[N]; int n,a[100]; struct node { int x; LL d; bool operator < (const node &rhs) const { return d>rhs.d; } }; priority_queue<node> q; void add_edge(int x,int y,int z) { to[x].push_back(y);len[x].push_back(z); } void dij() { for (ri i=0;i<a[1];i++) dis[i]=bmax+1; dis[0]=0; q.push((node){0,0}); while (!q.empty()) { int x=q.top().x; q.pop(); if (vis[x]) continue; vis[x]=1; for (ri i=0;i<to[x].size();i++) if (dis[to[x][i]]>dis[x]+len[x][i]) { dis[to[x][i]]=dis[x]+len[x][i]; q.push((node){to[x][i],dis[to[x][i]]}); } } } LL count(LL h,int i) { if (h<i) return 0LL; if (i==0) return h/a[1]; else return (h-i)/a[1]+1; } LL max(LL a,LL b){ if (a>b) return a; else return b; } int main(){ scanf("%d %lld %lld",&n,&bmin,&bmax); for (ri i=1;i<=n;i++) { scanf("%d",&a[i]); if (a[i]==1) { cout<<bmax-bmin+1<<endl; return 0; } } for (ri i=0;i<a[1];i++) for (ri j=2;j<=n;j++) add_edge(i,(i+a[j])%a[1],a[j]); dij(); LL ans=0; for (ri i=0;i<a[1];i++) { ans+=(count(bmax,i)-count(dis[i]-1,i))-max(count(bmin-1,i)-count(dis[i]-1,i),0LL); } printf("%lld\n",ans); }