題目描述
給定乙個 \(n\times m\) 的 \(01\) 矩陣,對於矩陣的每乙個位置,你需要對於這個位置上的值反轉,然後求出這個矩陣的秩的變化:+,-,0
可以將這個矩陣看成 \(n\) 個大小為 \([0,2^m)\) 的數,秩就是它們線性基的大小。
\(n,m\leq 1000\)
解法
我們判斷求出原先的 \(n\) 個向量在原來的線性基中是可以替代的還是不可替代的,這個可以記錄一下線性基每個向量對應的位置,然後求出把新加入的向量消成 \(0\) 需要用到哪些位置,那麼這些位置都是可以替代的,下面可以分這兩類討論:
如果這個向量是可以替代的,那麼反轉 \(j\) 位可以考慮成新增乙個 \(2^j\) 向量,這和原來的向量是獨立的,原來的向量還是可以被湊出來。那麼我們只需要考慮這個新增的向量能否被湊出來即可,對於每一位可以預處理這一位是否被湊出來。如果是那麼位為0
;否則為+
如果這個向量是不可替代的,那麼考慮如果原線性基不能湊出 \(2^j\) 秩一定是0
,然後如果湊出 \(2^j\) 包含這個向量,說明這個向量是必須使用的,而現在又要將其刪除後再新增,所以答案是0
;否則如果不必須使用這個向量那麼答案為-
可以用 \(\tt bitset\) 優化,時間複雜度 \(o(\frac)\)
#include #include using namespace std;
const int m = 1005;
int read()
while(c>='0' && c<='9')
return x*f;
}int n,m,ir[m],ok[m];bitsetb[m],p[m],use[m];
signed main()
a=a^b[j];nw=nw^p[j];
} if(!f) for(int j=1;j<=n;j++)
if(nw[j]) ir[j]=0;
} for(int i=1;i<=m;i++)
nw=nw^b[j];use[i]=use[i]^p[j];
} }for(int i=1;i<=n;i++,puts(""))
for(int j=1;j<=m;j++)
else
}}
省選集訓2022 模擬賽6
題目描述 定義長度為 n 的好串 s 滿足 給你長度為 n 的序列 a 和 v 分別表示原序列和價值序列。你每次可以選擇乙個原序列中的好串,將其刪除之後剩下的串會前後拼接。設這次刪除的長度是 l 那麼會得分 v l 問最大得分,不一定要把原序列刪完。n leq 400,v i leq 10 5,a ...
省選集訓2022 模擬賽10
題目描述 給定 n 個元素,每個元素有兩個屬性值 a i,b i 我們可以將其以任意順序排列,要最大化下式 min a i i cdot k max b i i cdot k n leq 10 5,a i,b i,kn leq 10 9 解法 應該是遇到困難退大火才對,直接使用列舉法,考慮列舉 m ...
省選集訓2022 模擬賽11
題目描述 n 個城市構成一棵樹,現在要求在一些城市中設定監測點,使得每個城市可以通過到監測點的距離區分出來 不同可以知道是到哪個監測點的距離,可以模擬為樹上的座標 給定 q 次修改,每次斷開邊 u,v 再連上邊 x,y 然後求出最小設定的監測點數目。解法 無根樹問題考慮定根,我們先列舉根強制根選取,...