[National Team] ink ink equation

Questions face
https://www.luogu.org/problem/P2371

answer

#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);
}

 

Guess you like

Origin www.cnblogs.com/shxnb666/p/11278406.html