洛谷 & bzoj連題面都不貼 & 題面
題目概述:給定n
nn個長為m
mm的01串,q
qq次詢問,每次給定乙個長為m
mm的目標串,求有多少種在n
nn個串間填「位與」和「位或」符的方法使得最終計算結果為目標串
考試時忘記拼接程式了/(ㄒoㄒ)/~~
對於10
%10\%
10%的部分分可以o(q
⋅2n)
o(q\cdot 2^n)
o(q⋅2n
)暴力列舉做
對於20
%20\%
20%的部分分可以dp轉移
對於每一位進行dp,最後合併,但不知道如何合併
對於每一位好像只有and
0and~0
and0
和o r1
or~1
or1才會改變當前運算結果,而且取決於最右邊的
鬼知道要轉換01串……
還是上面的,對於一位上的運算,只有最後出現的and
0and~0
and0
或者是or1
or~1
or1決定結果
將a nd
andan
d視作1,oror
or視作0,則可將填入的n
nn個運算子轉換成乙個長為n
nn的01串
發現如果這一位上最終結果為0,則最終一定有乙個and
0and~0
and0
的操作,如果結果為1,則最終一定有乙個or1
or~1
or1的操作,並且這個操作後的每一步都是and
1and~1
and1
或o r0
or~0
or0,即每一位都相等(都為1或都為0)
舉個例子,比如目標串當前位為1
11(第j
jj位),n
nn個串中對應的位置(第j
jj位)連起來形成的串a為01101010
01101010
011010
10,則操作串要求第7位為0,第7位後面的必須與串相同,而第7位前的無限制,用c表示這一位必須與串a對應位置相同,x表示這一位無限制,則合法的操作串為xxx
xxx0
c******0c
xx***x
0c如果將最後一位視作最高位,相當於操作串必須比串a小,相應的,如果目標串中為0
00,則操作串必須比串a大(這裡的大小比較規則是從最高位開始比較)
所以對於每乙個詢問,答案應該為所有為1的位置上對應串a中最小值減去所有為0的位置上對應串a中最大值
比如說詢問串01011
01011
01011,a
ia_i
ai表示第i
ii位對應的串a,則答案為min(
a2,a
4,a5
)−
max(a
1,a3
)\min(a_2,a_4,a_5)-\max(a_1,a_3)
min(a2
,a4
,a5
)−max(a
1,a
3)
至於每次詢問暴力取min
max
\min \max
minmax
,詢問總複雜度為o(q
⋅nm)
o(q\cdot nm)
o(q⋅nm
)(這也可能是出題人設定70
7070
分部分分的原因)
我們考慮先將m
mm個串a進行排序,這樣每次詢問時只要找到最左邊的1和最右邊的0即可,詢問複雜度o(q
⋅m
)o(q\cdot m)
o(q⋅m)
總複雜度o(n
m+qm
)o(nm+qm)
o(nm+q
m)真是人類智慧型題……
#include
using
namespace std;
typedef
long
long ll;
#define rg register
const
int n=
1010
,m=5010
,p=1000000007
;int sm[m]
,pw[n]
,a[m]
,b[m]
,cnt[2]
;char s[m]
;int n,m,q;
intmain()
while
(q--
)for
(rg int i=m;i;
--i)
if(s[a[i]]==
'0')
if(lputs
("0");
else
if(l!=m+1)
printf
("%lld\n",(
1ll*sm[a[l]]-
1ll*sm[a[r]
]+p)
%p);
else
printf
("%lld\n",(
1ll*pw[n+1]
-1ll
*sm[a[r]
]+p)
%p);
}return0;
}
HNOI2018尋寶遊戲
題解我們首先按位考慮。如果有一位最終的結果為1,那麼我們可以把樹的序列看成乙個二進位制數,先出現的在底位,後出現的在高位,操作序列也可以看做乙個二進位制數,and 為1,or 為0,先出現的在低位,後出現的在高位。首先操作序列是不可能把0變成1的,那麼要使最後的結果為1,就得考慮數字序列最高位的1,...
Hnoi2018 遊戲 拓撲排序
一次小g和小h在玩尋寶遊戲,有n個房間排成一列,編號為 1,2,n 1,2 n 相鄰的房間之間都有一道門。其中一部分們上鎖 因此需要有對應的鑰匙才能開門 其餘的門都能直接開啟。現在小g告訴了小h每把鎖的鑰匙在哪個房間裡 每把鎖鎖有且只有一把鑰匙與之對應 並作出p次指示 第i次讓小h從第 si s i...
5285 Hnoi2018 尋寶遊戲
鏈結分析 從下面依次確定運算符號,然後在確定的過程中,需要確定的位數會逐漸減少。比如最後有乙個1,如果在從下往上確定了乙個or 1,那麼再往前可以隨便選了。那麼就是要求從下往上,第乙個出現的or 1要在and 0之前。如果將這一位上的每乙個數字拿出來,從下往上構成乙個二進位制數a,把and看成1,o...