• 【国家集训队】墨墨的等式


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

    集训队的神题……
    怎么看都以为是数论题,结果是同余最短路……
    通过对所有数%k,跑最短路,求出在%k意义下的最小数
    那么在%k意义下的更大的数也一定可以抵达
    而且有点卡常,所以跑spfa的时候不用建边,直接跑就好了
    实乃思维神题啊……

    代码:

    #include<bits/stdc++.h>
    #define N 500005
    #define inf (1LL<<60)
    #define ll long long
    using namespace std;
    
    ll n,l,r,a[13],ans=0;
    
    template<class T>inline void read(T &res)
    {
    	char c;T flag=1;
    	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
    	while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    } 
    
    ll dis[N];
    bool vis[N];
    queue<ll> q;
    void spfa(int s)
    {
    	for(register int i=0;i<=a[1];++i) dis[i]=inf;
    	memset(vis,0,sizeof(vis));
    	q.push(s);
    	dis[s]=0;
    	vis[s]=1;
    	while(!q.empty())
    	{
    		int u=q.front();q.pop();vis[u]=0;
    		for(register int i=2;i<=n;++i)
    		{
    			int v=(u+a[i])%a[1];
    			if(dis[v]>dis[u]+a[i])
    			{
    				dis[v]=dis[u]+a[i];
    				if(!vis[v])
    				{
    					q.push(v);
    					vis[v]=1;
    				}
    			}
    		}
    	}
    }
    
    int main()
    {
    	read(n);read(l);read(r);
    	for(register int i=1;i<=n;++i) read(a[i]);
    	sort(a+1,a+n+1);
    	spfa(0);
    	for(register int i=0;i<a[1];++i)
    	{
    		if(dis[i]<=r)
    		{
    			if(dis[i]>=l) ans+=(r-dis[i])/a[1]+1;
    			else ans+=(r-dis[i])/a[1]+1,ans-=(l-dis[i]+a[1]-1)/a[1];
    		}
    	}
    	printf("%lld
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    数据结结构学习 赫夫曼树
    C++ 类中特殊的成员变量(常变量、引用、静态)的初始化方法
    Linux/Unix time时间戳的处理转换函数
    gcc中include文件的搜索路径
    数据结结构学习 2叉树
    C++ 虚函数表解析
    数据结结构学习 线性表
    C#实现MD5加密
    学习的艺术
    C# 3.0实现类本身的方法扩展
  • 原文地址:https://www.cnblogs.com/tqr06/p/11656300.html
Copyright © 2020-2023  润新知