bzoj2118 墨墨的等式 同餘最短路

2021-08-30 04:22:32 字數 2132 閱讀 6307

墨墨突然對等式很感興趣,他正在研究a1x

1+a2

x2+…

+anx

n=

ba_1x_1+a_2x_2+…+a_nx_n=b

a1​x1​

+a2​

x2​+

…+an

​xn​

=b存在非負整數解的條件

他要求你編寫乙個程式,給定n

,n,\

n,以及b

bb的取值範圍,求出有多少b可以使等式存在非負整數解。

n ≤12

,0≤a

i≤5×

105,

1≤bm

in≤b

max≤

10

12n\leq12,0\leq a_i\leq 5\times 10^5,1\leq b_ \leq b_ \leq 10^

n≤12,0

≤ai​

≤5×1

05,1

≤bmi

n​≤b

max​

≤101

2題目中要求的是非負整數解,於是我們可以把每乙個數看成乙個物品,求所有物品可以組成的體積。

但是直接跑揹包顯然是接受不了的

考慮到最後的體積集合,我們把它按照a[1](也就是任意乙個數)的剩餘類分類。

雖然可以組成的體積種類很多,但是按照剩餘類分類之後體積的種類就只有5e5種 於是我們只需要求出每乙個剩餘類最小的體積就好了,每乙個合法的體積一定可以表示成a[1

]×x+

ba[1]\times x+b

a[1]×x

+b。建圖其實也很簡單。

每乙個餘數代表乙個點,點u可以向點(v+

a[j]

)mod

a[1]

(v+a[j])\mod a[1]

(v+a[j

])mo

da[1

]連一條權值為a[j]的邊。

從0開始單源最短路即可以得到所有餘數的最小體積。

#include

#define rep(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)

#define debug(x) cout<<#x<<"="<#define pii pair

#define fi first

#define se second

#define mk make_pair

typedef

long

long ll;

using

namespace std;

void

file()

template

<

typename t>

void

read

(t &_)

while

(isdigit

(ch)

)__=

(__<<1)

+(__<<3)

+(ch^

'0')

,ch=

getchar()

; _=__*mul;

}const

int maxn=20;

const

int maxm=

5e5+10;

const

int maxe=

6e6+10;

int n,a[maxn]

;ll b0,b1,ans,w[maxe]

,dis[maxm]

;int beg[maxm]

,to[maxe]

,las[maxe]

,cnte=1;

void

add(

int u,

int v,ll val)

void

init()

priority_queue< pii,vector

,greater

>qu;

void

dijkstra()

}}}void

work()

printf

("%lld\n"

,ans);}

intmain()

bzoj 2118 墨墨的等式(同餘最短路)

題目大意 墨墨突然對等式很感興趣,他正在研究a1x1 a2y2 anxn b存在非負整數解的條件,他要求你編寫乙個程式,給定n 以及b的取值範圍,求出有多少b可以使等式存在非負整數解。這種題的主要思路就是,找到所有 之後只要不斷加上自己就都是合法的解,可以直接求和,那麼這個最小值怎麼找呢?只要利用最...

bzoj 2118 墨墨的等式

又是好一道數論題!令mn為a 1 a n 中數的最小值。很顯然,如果x能被湊出來,x mn也能被湊出來。所以我們只需要知道對於每乙個x屬於 0,mn 滿足y mn x中最小的y,那麼就能知道 1,r 中模mn等於x的數里能湊出來的個數。注意spfa的時候正無窮要大一點 需要特殊處理一下a 0的情況,...

bzoj2118 墨墨的等式

time limit 10 sec memory limit 259 mb submit 878 solved 337 submit status discuss description 墨墨突然對等式很感興趣,他正在研究a1x1 a2y2 anxn b存在非負整數解的條件,他要求你編寫乙個程式,給...