牛客50915題解

2021-09-25 16:44:35 字數 3018 閱讀 8583

題目鏈結(可能需要許可權)

題目大意:

給你n個集合,每個集合中都有不超過32個數,總共詢問m次,每次詢問區間 [l, r] 中的所有集合,是否都有乙個異或和等於x的子集。

n ≤

\le≤ 5e4,m ≤

\le≤ 5e4,所有數值域 [0, 2

322^

232]。

難度:ag+

分析:這個題很明顯,要求線性基的交,也就是說假設有a,b兩個線性基,要求出乙個線性基c,使得c表示的線性空間既包含於a所表示的線性空間,也包含於b所表示的線性空間。

下面先說線性基怎麼求交。如果我們有a,b兩個線性基,要求它們的交線性基c,那麼顯然b中所有能被a線性基表示的數,都要插入c中,之後如果 a ∪

\cup

∪ ( b ∖

\setminus

∖ c ) 線性無關(b ∖

\setminus

∖ c 代表b中所有不能被a線性基表示的數),則c就是a,b的交線性基。

但問題是 a ∪

\cup

∪ ( b ∖

\setminus

∖ c ) 未必線性無關,所以我們採取下面這種做法。再額外建立乙個線性基d,同時d上每一位再額外儲存乙個值v,一開始把a中所有的數字 a[i] 插入d,並把對應插入位置的v也改為 a[i]。之後從低位到高位,將b中每乙個數字 b[i] 插入d,每次插入時,維護乙個u值,u一開始等於1,插入時每訪問到d的某一位,u就等於u異或對應位上的v。

如果 b[i] 可以被d表示,那麼插入一定失敗,把 u 插入c;如果 b[i] 不可以被d表示,那麼一定會將乙個值x插入d中某一位,同時把對應位的v值改為u。這樣將b遍歷完畢之後,c就是a和b的交線性基。

現在我們會求線性基的交了,可以看出求兩個線性基的交,時間複雜度為o(log2

^2x),x為數的值域。之後比較明顯,我們可以用線段樹來維護區間的交線性基,每個非葉節點上的線性基等於其兩個子節點的交線性基,葉節點上的線性基等於對應位置上的集合的線性基。

^2

^2x + mlognlogx),n為集合數,m為運算元,x為數字的值域。

至於線性基求交的正確性,我們在這裡簡單證明一下。線性基求交的核心思想是,找到乙個所代表的線性空間等價於b的線性基b′

'′,將b′

'′中所有能被a表示的數字插入c′

'′,使得 a ∪

\cup

∪ ( b′'′∖

\setminus

∖ c′

'′) 線性無關。這樣c′

'′就是交線性基。

我們從低位到高位,將b中每乙個數字 b[i] 插入d。如果 b[i] 不可以被d表示,那麼把 b[i] 加入b′

'′;如果可以,那麼把u插入b′

'′,接下來我們只需要證明b′

'′所表示的線性空間等價於b所表示的。注意到u一定是d中某些位的v值的異或和,d中的這些位,可能原本來自於a,也可能來自於b[j] (j < i) 的插入,我們找到所有這樣的 j,記為 j1_1​

、j2 _2​

……然後計算 b[j1_1​

]、b[j2_2​

]……的異或和,記為sum,我們發現u = b[i] ^ sum(這裡不太好理解,可以自己在紙上算一下)。

對於b′

'′上的每一位b′

'′[i],它要麼等於b[i],要麼等於b[i] ^ b[j1_1​

] ^ b[j2_2​

]……(j1_1​

, j2_2​

…… < i),那麼顯然,b′

'′能由b經過初等變換得到,因此b′

'′所表示的線性空間等價於b所表示的。證畢。

**:

# include

# define maxn 50005

# define ls (cur << 1)

# define rs ((cur << 1) | 1)

typedef

unsigned uint;

struct sgt

x ^= a[cur]

[i];}}

void

push_up

(int cur)

//非葉節點上的線性基等於它的子節點的交線性基

x ^= t1[j]

; tmp ^

= t2[j];}

if(!x)insert

(tmp, cur);}

}void

build

(int left,

int right,

int cur)

return;}

int mid =

(left + right)

>>1;

build

(left, mid, ls)

;build

(mid +

1, right, rs)

;push_up

(cur);}

void

build

(int size)

char

query

(int x,

int y, uint val,

int left,

int right,

int cur)

int mid =

(left + right)

>>1;

char ret =1;

if(x <= mid)

ret &

=query

(x, y, val, left, mid, ls);if

(y > mid)

ret &

=query

(x, y, val, mid +

1, right, rs)

;return ret;

}char

query

(int x,

int y, uint val)};

sgt s;

intmain()

return0;

}

0208牛客題解

題意給乙個m行n列的二維字元陣列,全都有 b r d組成 r 只能往右走,d只能往下走,b往右走往下走都行問 走到 n,m點總共有多少種走法 思路 dfs 超時了,迭代 假設 a i j 是走向 i,j點的放法和 那麼 i 1,j 往下走就到了ij 點 那麼如果這點能往下走 就能把通向i 1,j的步...

牛客2 13題解

題意給兩字串,每次可以執行以下三種操作,1是將乙個字母變成乙個字母,另乙個就是從後面加乙個字母,再乙個就是從後面刪除乙個字母問最少可以轉換多少次讓這兩個字串相同 思路 這題其實特別簡單,就是先求兩個字串的長度差,這個長度差 肯定是轉換次數的一部分,用23其實都一樣,然後看 他們長度相同的那一段有多少...

牛客網 single number系列題解

給定乙個整型陣列,除乙個元素僅出現一次之外,其餘每個元素都出現兩次 三次 試著找出這個元素。此類題目,若每個元素出現i次,如果將問題的視角放在資料位上來看的話,實際上就是除那個 single number 所在的bits外,每個bit上出現資料的次數 i 0。1.兩次 a.常規思路 class so...