方程的解數 SSL 1127 並查集

2021-10-08 08:12:47 字數 2031 閱讀 4310

第1

11行包含乙個整數n

nn。第2

22行包含乙個整數m

mm。第3

33行到第n+2

n+2n+

2行,每行包含兩個整數,分別表示kiki

ki和p ipi

pi。兩個整數之間用乙個空格隔開。第3行的資料對應i=1

i=1i=

1,第n+2

n+2n+

2行的資料對應i=n

i=ni=

n。output

僅一行,包含乙個整數,表示方程的整數解的個數。

sample input

3150

1 2-1 2

1 2sample output

178解題思路

初看此題,題目要求出給定的方程解的個數,這個方程在最壞的情況下可以有6

66個未知數,而且次數由輸入決定。這樣就不能利用數學方法直接求出解的個數,而且注意到解的範圍最多150個數,因此恐怕只能使用列舉法了。

最簡單的思路是窮舉所有未知數的取值,這樣時間複雜度是 o(m

6)o(m^6)

o(m6

),無法承受。因此我們需要尋找更好的方法,縮小列舉的範圍也有很大的困難。我們再次注意到m

mm 的範圍,若想不超時,似乎演算法的複雜度上限應該是 o(m

3)o(m^3)

o(m3

) 左右,這是因為 1503

<

10000000

150^3 < 10000000

1503

<10

0000

00。我們要通過列舉3

33個未知數的值來找到答案,前一半式子的值 s

ss 可以確定,這時只要列舉後3

33 個數的值,檢查他們的和是否等於 −s-s

−s即可。當然還需要預先算出 1

11 到 150

15015

0的各個冪次的值。

**

#include

#include

#include

#include

using namespace std;

const int p=

4000037

;int n,m,mid,a[10]

,b[10

],cl[

155][7

],h[p][2

];long long ans;

void

ycl()}

int hash

(int x)

int work

(int x)

void

dfs(int dep,int s)

else

for(int i=

1;i<=m;i++

)dfs

(dep+

1,s+a[dep]

*cl[i]

[b[dep]])

;}void

dfs1

(int dep,int s)

}else

for(int i=

1;i<=m;i++

)dfs1

(dep+

1,s+a[dep]

*cl[i]

[b[dep]])

;}int main()

else

}

SSL 1127 方程的解數

我們可以把這個方程一半的加數移到右邊去,例k1x1p1 k2x2p2 k3x3p3 0移項變成k1x1p1 k2x2p2 k3x3p3可以減少我們列舉x的次數,用雜湊表存左邊求出的情況有哪些,在右邊列舉的時候我們就可以判斷是否和左邊相等,然後加上次數就可以了。include define maxn ...

SSL1127 方程的解數

第1行包含乙個整數n。第2行包含乙個整數m。第3行到第n 2行,每行包含兩個整數,分別表示ki和pi。兩個整數之間用乙個空格隔開。第3行的資料對應i 1,第n 2行的資料對應i n。僅一行,包含乙個整數,表示方程的整數解的個數。3 15012 1212 178它的x xx需要從1 m 1 m1 m列...

ssl1127 方程的解數 HASH,dfs

我只是湊數的。第1行包含乙個整數n。第2行包含乙個整數m。第3行到第n 2行,每行包含兩個整數,分別表示ki和pi。兩個整數之間用乙個空格隔開。第3行的資料對應i 1,第n 2行的資料對應i n。僅一行,包含乙個整數,表示方程的整數解的個數。3 150 1 2 1 2 1 2聽真正的dalao講的 ...