zoukankan      html  css  js  c++  java
  • BZOJ 2118: 墨墨的等式(最短路dijkstra+堆)


    2118: 墨墨的等式

      Time Limit: 10 Sec
      Memory Limit: 259 MB

    Description###

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

    Input###

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

    Output###

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

    Sample Input 1###

      2 5 10
      3 5
      

    Sample Output 1###

      5
      

    HINT###

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

    题目地址: BZOJ 2118: 墨墨的等式

    题解:

         
      每个数都能表示成(k*a[1]+x(0<=x<a[1]))的形式
      如果对于每个(x)我们求出最小的(k*a[1]+x)
      那么把([l,r])分成([1,l-1])([1,r])来做,就可以轻松统计答案
      问题就变成了如何求出最小的(k*a[1]+x)
      把每个(x)都当做一个点
      只需在(x)((x+a[j])) mod (a[1])之间连一条边权为(a[j])的边,再跑一遍最短路即可
    www.cnblogs.com/AGFghy/


    AC代码

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #define pa pair<ll,int>
    using namespace std;
    typedef long long ll;
    int n,num,now;
    int len[6000005],point[6000005],next[6000005],p[500005],head[500005],a[20];
    ll d[500005];
    ll l,r,nl,nr;
    void insert(int u,int v,int l)
    {
    	num++; len[num]=l; point[num]=v; next[num]=head[u]; head[u]=num;
    }
    void Dijkstra(int x)
    {
    	priority_queue<pa,vector<pa>,greater<pa> >q; 
        for (int i=0; i<=a[now]-1; i++)
            d[i]=(ll)1e60,p[i]=0;
        d[x]=0; q.push(make_pair(0,x));
        while (!q.empty())
        {
            int now=q.top().second; 
            p[now]=1;
            q.pop();
            for (int i=head[now]; i; i=next[i])
            {
                int v=point[i];
                if (p[v]) continue;
                if (d[now]+len[i]<d[v])
                {
                    d[v]=d[now]+len[i];
                    q.push(make_pair(d[v],v));
                }
            }
        }
    }
    int main()
    {
    	scanf("%d%lld%lld",&n,&l,&r);
    	l--;
    	for (int i=1; i<=n; i++)
    		scanf("%d",&a[i]);
    	sort(a+1,a+n+1);
    	now=1;
    	while (a[now]==0) now++;
    	for (int i=0; i<=a[now]-1; i++)
    		for (int j=2; j<=n; j++)
    			insert(i,(i+a[j])%a[now],a[j]);
    	Dijkstra(0);
    	for (int i=0; i<=a[now]-1; i++)
    		if (d[i]<=r)
    		{
    			if (l-d[i]>=0) nl+=((l-d[i])/a[now])+1;
    			if (r-d[i]>=0) nr+=((r-d[i])/a[now])+1;
    		}
    	printf("%lld
    ",nr-nl);
    }
    
  • 相关阅读:
    python中写一个求阶乘的函数
    python中filter关键字
    python中写一个求阶乘的函数
    python中如何获取函数文档
    python中lambda关键字创建匿名函数
    固态硬盘中m.2、sata、nvme、ahci、pcie是什么?
    python中lambda关键字定义匿名函数
    python中实现实参可选
    python中map()内置函数
    python中将实参变成可选的
  • 原文地址:https://www.cnblogs.com/AGFghy/p/9366363.html
Copyright © 2011-2022 走看看