傳送門
給定nn
n個長m
mm位的二進位制串
求乙個二進位制串t
tt,定義val
ival_i
vali是t
tt與第i
ii個二進位制串相同的位數
使得m ax
(val
1,va
l2..
..va
ln
)max(val_1,val_2....val_n)
max(va
l1,
val2
...
.val
n)最小,只需要輸出這個最小值。
因為總的狀態只有2
202^
220,要是能求出每個狀態到n
nn個串的max
maxma
x問題就迎刃而解了
如果把這n
nn個二進位制串的任何乙個作為t
tt,答案是m
mm,因為和自己所有位是相同的
而且改變自己任何一位二進位製作為t
tt,val
valva
l值就是m−1
m-1m−
1 但是結合只有最大的val
valva
l有用,我們想到了多起點bfs
bfsbf
s 把這n
nn個串拿去bfs
bfsbf
s,誰先到狀態k
kk,對k
kk而言誰就是最大的max
maxma
x 這樣每個狀態入隊一次,可以在優秀的複雜度內通過此題
#include
#include
#include
#include
#include
using
namespace std;
const
int maxn =
3e5+10;
queue<
int>q;
const
int inf =
1e9;
int f[
1<<21]
,n,m;
char s[maxn][25
];intmain()
//讓最大相似度最小
int ans = inf;
while
(!q.
empty()
)}}printf
("%d"
,ans)
;}
還有一種神仙做法二分+fw
t+fwt
+fwt
首先我們把讀入的串x
xx令a[x
]=
1a[x]=1
a[x]=1
然後假如知道了串t
tt,令b[t
]=
1b[t]=1
b[t]=1
,設答案為ans
ansan
s 這樣a
aa和b
bb做異或卷積得到ccc
c i=
∑j⊕k
=ibj
∗a
kc_i=\sum\limits_b_j*a_k
ci=j⊕
k=i∑
bj
∗ak
,有值的c
ic_i
ci滿足i
ii的二進位制0
00不超過ans
ansan
s 現在我們考慮逆過程,二分這個ans
ansan
s 那麼給c
cc陣列賦值,所有二進位制不大於ans
ansan
s個00
0的下標賦值為111
讓a
aa和c
cc做異或卷積可以得到陣列bbb
這個陣列b
bb的任意滿足b[i
]=
nb[i]=n
b[i]=n
就是可行的,因為對於b
ib_i
bi來說,a
aa的每個元素只能造成一點貢獻
#include
using
namespace std;
const
int maxn =
1<<23;
#define int long long
int a[maxn]
,b[maxn]
,bit[maxn]
,n,m,mx;
void
xor(
int f,
int type)
}bool
isok
(int x)
signed
main()
xor(a,1)
;int l =
0,r = m,ans=m;
while
( r>=l )
printf
("%lld"
,ans)
;}
牛客練習賽 41 D 最小相似度 BFS
題意 定義兩個位數相等的二進位制串的相似度sim a,b 二進位制串中a b中0的個數 sim left a,b right texta oplus b text sim a,b 二進位制串中a b中0的個數 給定n nn個長度為m mm的二進位制串。現在的問題是找出乙個額外的長度為m mm的二進位...
牛客練習賽41 D 最小相似度(BFS)
思路 m最大只有20,如果把每個二進位制串看成乙個狀態,最多只有2 20 1048576個狀態,可以暴力搜尋。如果我們把某個串改變1位,這個改變後的串和這個串的答案就是m 1,比如01001,隨便改變1位變成01000,01001 01000 00001 答案就是m 1。我們要找的是m x的最小值,...
題解 牛客練習賽41 D 最小相似度
題目鏈結 text 首先考慮我們到底要求啥,實際就是要快速求出對於乙個數 x,所有數與它異或後的sim值。一種 的想法是直接列舉 t,顯然複雜度 因為 n 太大了,是 o 2 m times n 的。考慮把 n 乾掉,倒著想。題目的描述引導我們去二分答案。設當前答案是 mid,目標就是看是否存在乙個...