先考慮\(k=2\)怎麼做。
注意到點積不為0就為1。
我們隨機乙個排列\(p[i]\),然後列舉\(i=1->n\),看看\(p[i]\)與\(p[1..i-1]\)的點積和\(s\)。
如果\(s≠(i-1)~mod~k\),則說明\(p[1..i-1]\)中一定有乙個向量和\(p[i]\)的點積\(=0\)。
此時暴力check就行了。
最壞情況一次check的錯誤概率是\(1/2\)。
所以做\(t=10\)次,時間複雜度:\(o(t*n*d)\)
\(k=3\)時,就不能這麼做了,因為點積不為0時可以為1、2
取點積的平方,一定就\(=1\)了,可以把式子拆開以快速計算點積的平方。
這裡複雜度就是:\(o(t*n*d^2)\)
code:
#include#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int n = 1e5 + 5;
int n, d, mo, a[n][100], b[100], c[100][100];
int p[n];
void check(int x) }}
int main()
} fo(i, 1, n) p[i] = i;
fo(t, 1, 10) else
s %= mo;
if(s != (i - 1) % mo)
if(mo == 2) else
} }pp("-1 -1\n");
}
NOI2013 向量內積
題面 題解窩本來想用這道題寫矩陣雜湊的,所謂矩陣雜湊,就是快速判斷兩個矩陣的乘積是不是另外乙個矩陣。矩陣雜湊就是隨機乙個向量,利用矩陣結合律先算向量和各矩陣的乘積,然後直接比較兩個向量是不是相等的。這樣本來是 n 3 的,就變成 n 2 的。但是看到題解第一種方法更簡便而且更易懂,就寫第一種方法了。...
NOI2013 向量內積
定義兩個 d 維向量 的內積為其相對應維度的權值的乘積和 a i b i 現在有 n 個 d 維向量,判斷是否存在兩個向量的內積為 k 的倍數 我們考慮將 n 個 d 維的向量構成乙個 n d 的矩陣 a a 為 a 的轉置矩陣。令矩陣 那麼 就表示了向量 i 與向量 j 的內積。直接判斷內積的值即...
矩陣乘法 NOI2013 向量內積
兩個 d 維向量 a a1,a2,ad 與 b b1,b 2,bd 的內積為其相對應維度的權值的乘積和,即 a b i 1 daib i a1 b1 a 2b2 ad bd現在有 n 個 d維向量 x1 x2,xn 小喵喵想知道是否存在兩個向量的內積為 k 的倍數。請幫助她解決這個問題。第一行包含 ...