zoukankan      html  css  js  c++  java
  • [国家集训队]墨墨的等式(最短路优化完全背包)


    题目描述

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

    输入格式

    输入的第一行包含3个正整数,分别表示NBMinBMax分别表示数列的长度、B的下界、B的上界。

    输入的第二行包含N个整数,即数列{an}的值。

    输出格式

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

    输入输出样例

    输入 #1
    2 5 10
    3 5
    输出 #1
    5

    说明/提示

    对于20%的数据,N5,1BMinBMax10。

    对于40%的数据,N10,1BMinBMax106。

    对于100%的数据,N12,0ai5105,1BMinBMax1012。

           十分神奇的思路。

           为了优化要选择minnum作为模数。

         复杂度十分神奇 并不会证qaqq

         

     1 #include<bits/stdc++.h>
     2 #define re register int
     3 #define LL long long
     4 #define maxn 12+5
     5 #define maxn1 500000+5
     6 #define maxn2 6000000+5
     7 using namespace std;
     8 
     9 
    10 
    11 int n;
    12 int num[maxn];
    13 bool vis[maxn1];
    14 LL bmin,bmax;
    15 LL dis[maxn1];
    16 struct edge
    17 {
    18     int nex,to,w;
    19 }ed[maxn2];
    20 int head[maxn1];
    21 int cnt,mintmp; 
    22 void add(int x,int y,int w)
    23 {
    24     ed[++cnt].to=y;
    25     ed[cnt].nex=head[x];
    26     ed[cnt].w=w;
    27     head[x]=cnt;
    28 } 
    29  queue<int>q;
    30  void spfa()
    31  {
    32      for(re i=0;i<mintmp;i++)
    33      dis[i]=1926081700000;
    34      q.push(0);
    35      vis[0]=true;
    36      dis[0]=0;
    37      //cout<<dis[1]<<endl;
    38      while(!q.empty())
    39      {
    40         int u=q.front();
    41         q.pop();
    42         vis[u]=false;
    43         for(re i=head[u];i;i=ed[i].nex)
    44             if(dis[ed[i].to]>dis[u]+ed[i].w)
    45         {
    46         dis[ed[i].to]=dis[u]+ed[i].w;
    47             if(!vis[ed[i].to]) {
    48                 q.push(ed[i].to);
    49                 vis[ed[i].to]=true;
    50             }
    51         }
    52      }
    53     }
    54 LL query(LL x)//LL x
    55 {
    56     LL ans=0;
    57     for(re i=0;i<mintmp;i++)
    58     if(dis[i]<=x)  ans+=(x-dis[i])/mintmp+1;
    59     //是<=而不是!=1926081700000  
    60     return  ans;
    61 }
    62 int main()
    63 {
    64     ios::sync_with_stdio(false);
    65     cin>>n>>bmin>>bmax;
    66     mintmp=maxn1;
    67     for(re i=1;i<=n;i++)
    68     {
    69         cin>>num[i];
    70         if(num[i])
    71         mintmp=min(mintmp,num[i]);
    72     } 
    73     for(re j=0;j<mintmp;j++)
    74     for(re i=1;i<=n;i++)
    75     if(num[i]!=mintmp) 
    76     add(j,(num[i]+j)%mintmp,num[i]);
    77     //由j向(num[i]+j)%mintmp连边 
    78     spfa();
    79     LL sum=query(bmax)-query(bmin-1);
    80 //    cout<<query(bmax)<<endl;
    81 //    cout<<query(bmin-1)<<endl; 
    82     cout<<sum;
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    处理excel表
    生成登陆验证码
    IKAnalyzer分词例子
    JAVA中不用+ 如何实现加法
    开发者应该掌握的Java代码优化技能
    Spring Boot Maven插件
    23种设计模式(1)-单例模式
    Spring AOP 创建切面
    Spring AOP 创建增强类
    Spring AOP基础知识
  • 原文地址:https://www.cnblogs.com/3200Pheathon/p/11620655.html
Copyright © 2011-2022 走看看