題目描述
有乙個 \(n\times n\) 的矩陣,初始時所有位置上都是 \(0\),每次你可以選擇若干行 \(r_1,r_2...r_p\) 和若干列 \(c_1,c_2...c_q\),把這些行列交點處的位置都變成 \(1\),即把 \((r_i,c_j),1\leq i\leq p,1\leq j\leq q\) 這些位置上的數字都變成 \(1\)
\(n\leq 3000\),詢問次數 \(\leq 26\)
解法
首先考慮簡化問題,如果只是對角線上的元素為 \(0\) 怎麼辦?由於同行同列不能同時選,可以考慮二進位制分組。對於每個二進位制位,每次把為 \(0\) 的行和為 \(1\) 的列(還有為 \(1\) 的行和為 \(0\) 的列)拿出來做,這樣乙個點由於其橫縱座標不同,一定會在橫縱座標不同的那個二進位制位上被染黑,詢問次數 \(2\log n\)
本題就是多了對角線下面的那一列,嘗試把上面的做法拓展下來。我們把列奇偶分組,把奇數列和所有的行做,把偶數列和所有的行做。比如在做奇數列的時候,我們可以把 \(1,2\) 壓縮成一行,這樣就轉化到了上面的情況。
但是好像要花費 \(4\log n\) 的詢問次數,其實對角線的問題是可以做到 \(1\log n\) 的,具體來說我們把行和列都重新編號。值域為 \([0,2^)\),我們只把有 \(6\) 個 \(1\) 的數取出來,給它們重編號,這樣每次只用把為 \(0\) 的行和為 \(1\) 的列拿出來做。
這是因為重編號方式不存在數字的包含關係,所以一定存在行的某個數字是 \(0\),列的某個數字是 \(1\),因為 \(>1500\),所以編號也是夠用的,那麼我們就把詢問次數優化到了 \(2\log n\)
#include #include using namespace std;
const int m = 3005;
#define pb push_back
int read()
while(c>='0' && c<='9')
return x*f;
}int n,m,k,bit[1<<13],id[1<<13],a[m],b[m];
vectora[m],b[m];
int main()
for(int i=1;i<=n;i+=2)
a[i]=b[i]=b[i+1]=id[(i+1)>>1];
for(int t=0;t<13;t++)
//for(int i=0;i<=n;i+=2)
a[i]=b[i]=b[i+1]=id[(i+2)>>1];
for(int t=0;t<13;t++)
printf("%d\n",k);
for(int i=1;i<=k;i++)
}
國賽模擬總結
題目 2018b題 智慧型r 的動態排程策略 圖1是乙個智慧型加工系統的示意圖,由8臺計算機數控工具機 computer number controller,cnc 1輛軌道式自動引導車 rail guide vehicle,r 1條r 直線軌道 1條上料傳送帶 1條下料傳送帶等附屬裝置組成。r 是...
省選集訓2022 模擬賽6
題目描述 定義長度為 n 的好串 s 滿足 給你長度為 n 的序列 a 和 v 分別表示原序列和價值序列。你每次可以選擇乙個原序列中的好串,將其刪除之後剩下的串會前後拼接。設這次刪除的長度是 l 那麼會得分 v l 問最大得分,不一定要把原序列刪完。n leq 400,v i leq 10 5,a ...
省選集訓2022 模擬賽8
題目描述 給定乙個 n times m 的 01 矩陣,對於矩陣的每乙個位置,你需要對於這個位置上的值反轉,然後求出這個矩陣的秩的變化 0 可以將這個矩陣看成 n 個大小為 0,2 m 的數,秩就是它們線性基的大小。n,m leq 1000 解法 我們判斷求出原先的 n 個向量在原來的線性基中是可以...