• 【BZOJ2118】墨墨的等式 最短路


    【BZOJ2118】墨墨的等式

    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。

    题解:这是一个经典的套路~

    由于ai的值<=5*10^5,所以我们随便选择其中的一个a1,然后建出一个a1个点的图,对于所有点i和数j,从i向(i+aj)%a1连边,长度为(i+aj)/a1。这样以来,从0到i的最短路长度就等于:最小的%a1=i的数/a1的值。然后统计答案即可,统计时注意一下边界条件的判断。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <queue>
    using namespace std;
    const int maxn=500010;
    typedef long long ll;
    queue<int> q;
    int n;
    int inq[maxn];
    ll m,L,R,ans;
    ll dis[maxn],v[20];
    int main()
    {
    	memset(dis,0x3f,sizeof(dis));
    	scanf("%d%lld%lld",&n,&L,&R);
    	int i,u;
    	for(m=1<<30,i=1;i<=n;i++)	scanf("%lld",&v[i]),m=min(m,v[i]);
    	dis[0]=0,q.push(0);
    	while(!q.empty())
    	{
    		u=q.front(),q.pop(),inq[u]=0;
    		for(i=1;i<=n;i++)
    		{
    			if(dis[(u+v[i])%m]>dis[u]+(u+v[i])/m)
    			{
    				dis[(u+v[i])%m]=dis[u]+(u+v[i])/m;
    				if(!inq[(u+v[i])%m])	q.push((u+v[i])%m);
    			}
    		}
    	}
    	for(i=0;i<m;i++)	if((R-i)/m>=dis[i])	ans+=(R-i)/m-max((L-1-i)/m,(ll)dis[i]-1);
    	printf("%lld",ans);
    	return 0;
    }
  • 相关阅读:
    Serveral effective linux commands
    Amber learning note A8: Loop Dynamics of the HIV-1 Integrase Core Domain
    amber初学……
    anaconda使用
    python中的一些语法
    python中的OOP
    python中的模块
    将python程序打包成exe
    python-执行过程
    python基础
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7859733.html
Copyright © 2020-2023  润新知