1. 程式人生 > 其它 >NOI2013向量內積

NOI2013向量內積

...

Link

非常巧妙的一道題目,記錄一下。

暴力分給的很足, \(O(n^2d)\) 可以拿60pts。

做的時候思路比較混亂,最初的想法是嘗試用矩陣來實現一個\(\prod^{t-1}_{i=1}vec_{i}\cdot vec_{t}\) 來判斷是否有0。

最後迷迷糊糊地發現這個東西不可做,但是得到了這樣的一個矩陣:

\[\begin{bmatrix} 1&0&0&0&0\\ 0&1&0&0&0\\ 0&0&1&0&0\\ 0&0&0&1&0\\ a_{1}&a_{2}&a_{3}&a_{4}&1\\ \end{bmatrix} \begin{bmatrix} b_{1}\\ b_{2}\\ b_{3}\\ b_{4}\\ 0 \\ \end{bmatrix} \]

可以發現這個東西非常雞肋,只能求一個向量內積的字首和,並沒有什麼用。

但是仔細想想,會發現當 \(k=2\) 的時候,假設當前列舉到了 \(i\) ,那麼可以根據這個矩陣最後得到的向量的最後一維是否是 \(i-1\) 來判斷是否存在內積為 \(0\) 的組合(因為每一對不為0的貢獻是 \(i-1\)

可是並沒有辦法去得到\(\sum^{t-1}_{i=1}(vec_{i} \cdot vec_{t}) \mod 2\),得到的是(\sum^{t-1}{i=1}vec{i} \cdot vec_{t}) \mod 2

再然後思路就斷掉了...

非常可惜,這裡已經離正解不遠了。

在看了一眼題解之後,發現

對於碰到的這個問題,可以通過random_shuffle之後多次判斷來解決。

毛估估一下,即使是最壞情況下每次得到正確答案的概率也是 \(\frac{1}{2}\),大概做10次就行了。

可是這樣子做複雜度是 \(O(nd^3)\) 的,還跑不過暴力,需要嘗試發現特殊性質

然後是對於上面的這個矩陣得到字首和的方法,在嘗試使用分配律得到特殊型別的矩陣來優化複雜度的時候,發現它本質上其實就是在做 \(\sum^{n-1}_{i=1}\sum^{d}_{j=1}a_{t,j}a_{i,j}\)

所以折騰了半天其實都是在幹無意義的事情

這裡交換一下列舉順序,然後字首和優化,就不難得到一個 \(O(nd)\) 的做法。

\(k=3\) 的時候發現有 \(1^2 = 2^2 \mod 3\)

所以實際上跟上面差不多。

\[\begin{aligned} \sum^{t-1}_{i=1}(x_{i} \cdot x_{t})^2&=\sum^{t-1}_{i=1}\sum^{d}_{x=1}a_{t,x}a_{i,x}\sum^{d}_{y=1}a_{t,y}a_{i,y}\\ &=\sum^{t-1}_{i=1}\sum^{d}_{x=1}\sum^{d}_{y=1}a_{t,x}a_{i,x}a_{t,y}a_{i,y}\\ &=\sum^{d}_{x=1}\sum^{d}_{y=1}\sum^{t-1}_{i=1}a_{t,x}a_{i,x}a_{t,y}a_{i,y}\\ &=\sum^{d}_{x=1}\sum^{d}_{y=1}a_{t,x}a_{t,y}\sum^{t-1}_{i=1}a_{i,x}a_{i,y}\\ \end{aligned} \]

複雜度 \(O(nd^2)\) ,也可以輕鬆通過。