题解P2371 [国家集训队]墨墨的等式

题目:P2371 [国家集训队]墨墨的等式

同余最短路的固定套路:排序,选最小的,在它的剩余系下跑spfa,注意把0去掉,否则会喜提0分。。。
 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #define it register int
 5 #define il inline
 6 #define rll register long long 
 7 using namespace std;
 8 typedef long long ll;
 9 const ll inf=4557430888798830399ll;
10 const int N=2000005;
11 const int M=(1<<20)-1;
12 ll m1,m2,fir,d[N],li,ri,ans;
13 int n,cnt,q[N],top1,top2,a[N];
14 bool inq[N];
15 il void fr(int &num){
16     num=0;char c=getchar();int p=1;
17     while(c<'0'||c>'9') c=='-'?p=-1,c=getchar():c=getchar();
18     while(c>='0'&&c<='9') num=num*10+c-'0',c=getchar();
19     num*=p;
20 }   
21 il void spfa(){
22     memset(d,0x3f,sizeof(d)),q[1]=0,d[0]=0,top1=0,top2=1,fir=a[1];
23     while(top1!=top2){
24         it top=q[(++top1)&M];
25         for(it i=2,x;i<=n;++i)
26             if(d[x=(top+a[i])%fir]>d[top]+a[i]){
27                 d[x]=d[top]+a[i];
28                 if(!inq[x]) q[(++top2)&M]=x;
29             }
30         inq[top]=false;
31     }
32 }
33 il ll Min(rll p,rll q){
34     return p<q?p:q;
35 }
36 il ll Max(rll p,rll q){
37     return p>q?p:q;
38 }
39 int main(){ 
40     fr(n),scanf("%lld%lld",&m1,&m2);
41     for(it i=1,x;i<=n;++i){
42         fr(x);
43         if(x) a[++cnt]=x;
44     }
45     n=cnt,sort(a+1,a+1+n),spfa();
46     for(it i=0;i<a[1];++i)
47         if(d[i]!=inf) d[i]=(d[i]-i)/a[1],li=Max(0,(m1-1-i)/a[1]-d[i]+1),ri=Max(0,(m2-i)/a[1]-d[i]+1),ans=ans-li+ri;
48     printf("%lld",ans);
49     return 0;
50 }
View Code

 

 

posted @ 2019-10-20 22:25  kylin_xy  阅读(178)  评论(0)    收藏  举报