[国家集训队] 墨墨的等式

洛谷 P2371 传送门

还是同余最短路啊,类似跳楼机那道题。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define ll long long
 6 using namespace std;
 7 
 8 int n,x;
 9 ll mx,mn;
10 int hd[500005],to[5500005],nx[5500005],ec;
11 ll len[5500005];
12 ll dis[500005];
13 bool vis[500005];
14 int a[15];
15 
16 void edge(int af,int at,ll el)
17 {
18     to[++ec]=at;
19     nx[ec]=hd[af];
20     hd[af]=ec;
21     len[ec]=el;
22 }
23 
24 struct data
25 {
26     int p;
27     ll d;
28     friend bool operator < (data q,data w)
29     {
30         return q.d>w.d;
31     }
32 };
33 
34 priority_queue<data>qq;
35 
36 void dijkstra()
37 {
38     memset(dis,0x3f,sizeof(dis));
39     dis[0]=0;
40     qq.push((data){0,0});
41     while(!qq.empty())
42     {
43         data nw=qq.top();
44         qq.pop();
45         if(vis[nw.p])continue;
46         vis[nw.p]=1;
47         for(int i=hd[nw.p];i;i=nx[i])
48         {
49             if((!vis[to[i]])&&dis[to[i]]>nw.d+len[i])
50             {
51                 dis[to[i]]=nw.d+len[i];
52                 qq.push((data){to[i],dis[to[i]]});
53             }
54         }
55     }
56 }
57 
58 int main()
59 {
60     scanf("%d%lld%lld",&n,&mn,&mx);
61     for(int i=1;i<=n;i++)
62     {
63         scanf("%d",&a[i]);
64         if(!a[i])n--,i--;
65     }
66     x=a[n],mn--;
67     for(int i=1;i<n;i++)
68     {
69         for(int j=0;j<x;j++)
70             edge(j,(j+a[i])%x,(ll)a[i]);
71     }
72     dijkstra();
73     ll ans1=0,ans2=0;
74     for(int i=0;i<x;i++)
75     {
76         if(dis[i]<=mx)ans1+=(mx-dis[i])/x+1;
77         if(dis[i]<=mn)ans2+=(mn-dis[i])/x+1;
78     }
79     printf("%lld",ans1-ans2);
80     return 0;    
81 }
原文地址:https://www.cnblogs.com/eternhope/p/9818926.html