• Bzoj2118 墨墨的等式


    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 1488  Solved: 578

    Description

    墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N、{an}、以及B的取值范围,求出有多少B可以使等式存在非负整数解。

    Input

    输入的第一行包含3个正整数,分别表示N、BMin、BMax分别表示数列的长度、B的下界、B的上界。输入的第二行包含N个整数,即数列{an}的值。

    Output

    输出一个整数,表示有多少b可以使等式存在非负整数解。

    Sample Input

    2 5 10
    3 5

    Sample Output

    5

    HINT

    对于100%的数据,N≤12,0≤ai≤5*10^5,1≤BMin≤BMax≤10^12。

    Source

    同余类最短路

    在所有读入的a[i]中,找到最小的一个a为基准,在模a的意义下计算问题

    假设通过一些数可以凑出x,使得x%a==j,那么通过累加a就可以凑出所有%a==j的大数。

    设dis[i]表示能凑到的模a余i的最小数,SPFA算出dis数组,再利用dis计算Bmin~Bmax内可以凑出的数的个数。

    一:刚开始写了建边的版本,但是因为要连的边太多了,常数爆炸,4000+ms通过

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #define LL long long
     7 using namespace std;
     8 const int mxn=500100;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 struct edge{
    16     int v,nxt;
    17     LL dis;
    18 }e[mxn*10];
    19 int hd[mxn],mct=0;
    20 void add_edge(int u,int v,LL dis){
    21     e[++mct].v=v;e[mct].nxt=hd[u];e[mct].dis=dis;hd[u]=mct;return;
    22 }
    23 int n;
    24 LL B1,B2;
    25 LL dis[mxn];
    26 int a[20];
    27 bool inq[mxn];
    28 queue<int>q;
    29 void SPFA(){
    30     memset(dis,0x3f,sizeof dis);
    31     q.push(0);inq[0]=1;dis[0]=0;
    32     while(!q.empty()){
    33         int u=q.front();q.pop();inq[u]=0;
    34         for(int i=hd[u];i;i=e[i].nxt){
    35             int v=e[i].v;
    36             if(dis[v]>dis[u]+e[i].dis){
    37                 dis[v]=dis[u]+e[i].dis;
    38                 if(!inq[v]){
    39                     inq[v]=1;
    40                     q.push(v);
    41                 }
    42             }
    43         }
    44     }
    45     return;
    46 }
    47 LL query(LL x){
    48     LL res=0;
    49     for(int i=0;i<a[1];i++){
    50         if(dis[i]<=x)res+=(x-dis[i])/(LL)a[1]+1;
    51     }
    52     return res;
    53 }
    54 int main()
    55 {
    56     scanf("%d%lld%lld
    ",&n,&B1,&B2);
    57     int i,j;
    58     for(i=1;i<=n;i++){
    59         a[i]=read();
    60         if(!a[i]){i--;n--;}
    61     }
    62     sort(a+1,a+n+1);
    63     
    64     for(i=1;i<=n;i++)
    65         for(j=0;j<a[1];j++){
    66             add_edge(j,(j+a[i])%a[1],a[i]);
    67         }
    68     SPFA();
    69 //    for(i=0;i<a[1];i++)printf("%d ",dis[i]);
    70     LL ans=query(B2)-query(B1-1);
    71     printf("%lld
    ",ans);
    72     return 0;
    73 }
    邻接表

    二:改成了不具体建边的写法,只需要1000+ms

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #define LL long long
     7 using namespace std;
     8 const int mxn=500010;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 int n;
    16 LL B1,B2;
    17 LL dis[mxn];
    18 int a[20];
    19 bool inq[mxn];
    20 queue<int>q;
    21 void SPFA(){
    22     memset(dis,0x3f,sizeof dis);
    23     q.push(0);inq[0]=1;dis[0]=0;
    24     while(!q.empty()){
    25         int u=q.front();q.pop();inq[u]=0;
    26         for(int i=2;i<=n;i++){
    27             int v=(u+a[i])%a[1];
    28             if(dis[v]>dis[u]+a[i]){
    29                 dis[v]=dis[u]+a[i];
    30                 if(!inq[v]){
    31                     inq[v]=1;
    32                     q.push(v);
    33                 } 
    34             }
    35         }
    36     }
    37     return;
    38 }
    39 LL query(LL x){
    40     LL res=0;
    41     for(int i=0;i<a[1];i++){
    42         if(dis[i]<=x)res+=(x-dis[i])/(LL)a[1]+1;
    43     }
    44     return res;
    45 }
    46 int main()
    47 {
    48     scanf("%d%lld%lld
    ",&n,&B1,&B2);
    49     int i,j;
    50     for(i=1;i<=n;i++){
    51         a[i]=read();
    52         if(!a[i]){i--;n--;}
    53     }
    54     sort(a+1,a+n+1);
    55     SPFA();
    56     LL ans=query(B2)-query(B1-1);
    57     printf("%lld
    ",ans);
    58     return 0;
    59 }
  • 相关阅读:
    hdu 1715 大菲波数
    Netty 应用程序的一个一般准则:尽可能的重用 EventLoop,以减少线程创建所带来的开销。
    引入 netty网关,向flume提交数据
    JavaBean的任务就是: “Write once, run anywhere, reuse everywhere” Enterprise JavaBeans
    API网关+Kubernetes集群的架构替代了传统的Nginx(Ecs)+Tomcat(Ecs)
    tmp
    全量日志 requestId
    googlr 黄金法则 监控
    数据链路层3个基本问题
    netty4.x 实现接收http请求及响应
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6131409.html
Copyright © 2020-2023  润新知