• 【图论经典题目讲解】洛谷 P2371 墨墨的等式


    P2371 墨墨的等式

    D e s c r i p t i o n \mathrm{Description} Description

    求解有多少个 b ∈ [ l , r ] b\in [l,r] b[l,r] 满足 ∑ i = 1 n a i x i = b \sum\limits_{i=1}^n a_ix_i=b i=1naixi=b 存在非负整数解( x i x_i xi 为变量, a a a 数组给定)。

    S o l u t i o n \mathrm{Solution} Solution

    b b b 一定可以表示为 q + k v q+kv q+kv 的形式,其中 q ∈ [ 0 , v ) q\in [0,v) q[0,v) 表示余数, k ∈ Z k\in \mathbb{Z} kZ

    故,思路可以转化为选择合适的 v v v,对于枚举余数 q ∈ 0 ∼ v − 1 q\in 0\sim v - 1 q0v1,求解通过 ∑ i = 1 n a i x i = b \sum\limits_{i=1}^n a_ix_i=b i=1naixi=b,所能凑出的最小的 b b b,使得 b b b v v v q q q

    那么,为了能够不重不漏的计算出所有的 b b b v v v 应取 min ⁡ ( a i ) \min(a_i) min(ai),即 a a a 数组中的最小值,这样只要能够由题目中的等式凑出的 b b b,就必定能由 q + k v q+kv q+kv 的形式。(可以感性理解)

    下面就是如何能够求解最小的余数为 q q q 出的 b b b q ∈ [ 0 , v − 1 ] q\in[0,v-1] q[0,v1]),这就运用到了 同余最短路

    将余数 i i i 连一条向 ( i + a j )   m o d   v (i+a_j)\bmod v (i+aj)modv 长度为 a j a_j aj 的边,对于每一个 j ∈ [ 1 , n ] j\in [1,n] j[1,n]。这表示从 i i i 这个余数加入 a j a_j aj 后,将会变为的一个新的余数。在这个图中求从 0 0 0 号点到所有点的最短路后,对于 i i i 号点的含义就是凑出余数为 i i i 的最小的数。

    最后,通过前缀和的思想可以得到 l ∼ r l\sim r lr b b b 的个数为 0 ∼ r 0\sim r 0r b b b 的个数减去 0 ∼ l − 1 0\sim l-1 0l1 b b b 的个数。对于每一个 i i i,设凑数余数为 i i i 的最小的数为 b ′ b' b,则若当前最高限制为 x x x,则 b b b 的个数为 ⌊ x − b ′ v ⌋ + 1 \lfloor\frac{x-b'}{v}\rfloor+1 vxb+1

    C o d e Code Code

    #include 
    #define int long long
    
    using namespace std;
    
    typedef pair<int, int> PII;
    typedef long long LL;
    
    const int SIZE = 5e6 + 10;
    
    int N, L, R;
    int A[20];
    int h[SIZE], e[SIZE], ne[SIZE], w[SIZE], idx;
    int Dist[SIZE], Vis[SIZE];
    
    void add(int a, int b, int c)
    {
    	e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++;
    }
    
    void Dijkstra(int Start)
    {
    	memset(Dist, 0x3f, sizeof Dist);
    	memset(Vis, 0, sizeof Vis);
    	priority_queue<PII, vector<PII>, greater<PII>> Heap;
    	Heap.push({0, Start}), Dist[Start] = 0;
    
    	while (Heap.size())
    	{
    		auto Tmp = Heap.top();
    		Heap.pop();
    
    		int u = Tmp.second;
    		if (Vis[u]) continue;
    		Vis[u] = 1;
    
    		for (int i = h[u]; ~i; i = ne[i])
    		{
    			int j = e[i];
    			if (Dist[j] > Dist[u] + w[i])
    			{
    				Dist[j] = Dist[u] + w[i];
    				Heap.push({Dist[j], j});
    			}
    		}
    	}
    }
    
    signed main()
    {
    	cin.tie(0);
    	cout.tie(0);
    	ios::sync_with_stdio(0);
    
    	memset(h, -1, sizeof h);
    
    	cin >> N >> L >> R;
    
    	int Min = 1e18;
    	for (int i = 1; i <= N; i ++)
    	{
    		cin >> A[i];
    		if (A[i]) Min = min(Min, A[i]);
    	}
    
    	for (int i = 0; i < Min; i ++)
    		for (int j = 1; j <= N; j ++)
    			if (A[j] != Min && A[j])
    				add(i, (i + A[j]) % Min, A[j]);
    
    	Dijkstra(0);
    
    	int Tot1 = 0, Tot2 = 0;
    	for (int i = 0; i < Min; i ++)
    		if (Dist[i] <= R)
    			Tot1 += (R - Dist[i]) / Min + 1;
    	for (int i = 0; i < Min; i ++)
    		if (Dist[i] < L)
    			Tot2 += (L - 1 - Dist[i]) / Min + 1;
    
    	cout << Tot1 - Tot2 << endl;
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
  • 相关阅读:
    时钟的同步与异步问题
    C++简单上手helloworld 以及 vscode找不到文件的可能性原因
    IDEA 整合 Tomcat 开发 Javaweb 工程 2022-7-28
    LeetCode 周赛 340,质数 / 前缀和 / 极大化最小值 / 最短路 / 平衡二叉树
    Vuex是什么?
    企业为何刚需CRM软件系统
    交叉验证太重要了!
    Java:基础语法2
    为什么你的小红书笔记总是没有什么阅读量?
    在应用内维护域名缓存时遇到的问题
  • 原文地址:https://blog.csdn.net/weixin_66946161/article/details/136126504