我們可以把染黑看成刪掉這條邊,那麼每次相當於是,如果存在乙個點有且僅有一條出邊,那麼把這條邊也刪掉,最後要刪完所有的邊。其實就dfs出一棵樹然後統計dfs樹之外有多少邊沒有被遍歷好了……那麼我們考慮乙個環,可以發現這個環如果一條邊都不刪,那麼最後一定會被留下來,因為每個點都至少有兩個出邊。
所以,在初始的邊刪完之後,圖一定得要無環。我們考慮乙個無環的圖,可以發現他就是乙個森林。考慮森林的葉子節點,可以發現每次葉子節點的父邊都會被刪掉,而刪掉之後森林還是森林。因此,在有限步操作之後,所有的邊都會被刪掉,所以無環就一定合法了。
因此我們最後的答案就是,給每個聯通塊都保留乙個生成樹,其他邊全都刪掉。
考慮這個東西怎麼算。因為一棵生成樹的邊數是點數減一,所有聯通塊的總點數是 n,所以如果設聯通塊數為 c,則最後剩下的邊個數就是 n - c,因此答案就是m−n
+cm−
n+c。
時間複雜度: θ(n
α(n)
+m)θ
(nα(
n)+m
)
code:
#include
#include
#include
#include
#include
#define ll long long
#define inf 0x7fffffff
#define re register
using
namespace std;
intread()
while
(ch <=
'9'&& ch >=
'0')
return x * f;
}int n,m,x,y,ans,cnt,d[
100005
],du[
100005
],vis[
100005];
struct edgee[
500005];
struct node};
void
add(
int x,
int y)
inte
(int x)
void
dfs(
int u)
}int
main()
for(
int i =
1; i <= n; i++)if
(!vis[i]
)dfs
(i);
printf
("%d\n"
,m - ans)
;return0;
}
考慮二分答案,則問題變為了求 [1, m] 內有多少個數字在至少乙個 s(ni) 裡面。考慮容斥:我們考慮先計算出有多少個 [1, m] 中的數在 s(n1), s(n2), · · · , s(nk)中,然後把它們都加起來。
顯然這樣算多了:如果某個數字同時在多個 s(ni) 裡面,那麼他就重複了。於是我們考慮再去掉在至少兩個 s(ni) 中的,然後加上至少三個 s(ni) 中的,去掉至少四個 s(ni) 中的……
那麼我們現在相當於是需要考慮乙個 的子集 n,計算有多少個數字 x ∈ [1, m],滿足 ∀t ∈ n,有 x ∈ (t)。可以發現, ∪t∈ns(t) = s(lcmt∈n(t)),因此可以直接二分得到這樣的 x 個數。
直接列舉 s 進行計算的時間複雜度為 θ(q · 2k · log2 2 m),可以通過子任務 3。
注意到我們最終的答案只與 lcmt∈n(t) 有關,因此我們可以考慮 dp:設 fi,t 表示考慮 n1, n2, · · · , ni,從中選出乙個子集,滿足他們的 lcm 是 t 的容斥係數之和。
注意到當 lcmt∈n(t) ≥ 60 時,一定不存在這樣的 x(因為答案不超過 1017,所以m ≤ 1017)。於是在 dp 的第二個維度只保留不超過 60 的那些值即可。
時間複雜度: θ(q(k log2 m + log3 2 m))。
3.1 按位與我們按照從高位到低位的順序進行貪心,如果當前位有至少兩個數字是 1,那麼我們可以讓這一位是 1,因此最終答案的這一位一定是 1。
那麼如果我們確定了某一位是 1,我們最後選擇的兩個數的這一位都得是 1,所以我們可以去掉所有這一位為 0 的數字,然後繼續向下貪心即可。最後的方案數就是剩餘的數字中選出兩個的方案數。
時間複雜度: θ(n log2 ai)。
3.2 按位異或
同樣地從高到低貪心,逐位確定。但是直接確定下來某一位是 1 並不能和按位與那樣減少候選範圍。
考慮先確定最後選擇的乙個數字 ai,考慮如何求出另乙個 aj 使得 ai xor aj 最大。
考慮將所有數字建出乙個 trie 樹,然後同樣從高到低進行貪心:如果當前位可以取得和 ai 這一位不一樣,那麼就取不一樣的,否則取一樣的。方案數可以在 trie 樹的每個節點上儲存對應數字個數得到。
時間複雜度: θ(n log2 ai)。
3.3 按位或
同樣地在確定了乙個數之後從高到低貪心。但是這裡又多了乙個問題:如果這個數字的當前位是 1,那麼我們仍然沒法減少候選範圍。
那麼在貪心到某一步之後,相當於是給定乙個位的集合 s,判斷是否乙個數的這些位都是 1,其餘位不管。接下來我們用 ai 表示數字 ai 中 1 的位置集合。
考慮 dp(事實上,這個 dp 方法叫做高維字首和):設 fi,s 表示使得 s ⊆ at 且at \ s ⊆ 的 t 的個數。那麼轉移時,考慮 at 的當前位是 0 還是 1,然後可以變成 fi-1,s 以及 fi-1,s 兩種,直接相加即可。
那麼我們就可以判斷是否存在乙個合法的數字了。最後的方案數同樣可以使用這個 dp 陣列求出。
時間複雜度: θ(ai log2 ai)。
正睿 2018 提高組十連測 Day5
鴨血居然沒想到字首和優化dp,主要是寫的是刷表.只想到線段樹優化,還要兩棵.首先是暴力解法 f i j f i 1 k 0 k j 2 嗯.這個顯然可以字首和優化.然後是正常人dp解法 令f i,j 表示長度為i總和為j的合法陣列個數 則f i j f i j 1 f i 1 j 2 第二項只有j為...
2019暑假正睿集訓8 10day7題解及總結
50pts 80pts 這道題直接暴力搜尋,每次在三個符號中任選乙個,按題意合併數。當合併了還剩兩個數的時候,就判斷它們選哪種符號最終能為1,找到一種ans 1 100pts 優化1 位運算。把輸 串按照fft初始化 法 樣bitrev 下就可以 位運算優化。優化2 四 當串 之後16的時候預處理。...
2019暑假正睿集訓8 5day2題解及總結
題目分析 一張圖里兩棵樹,每個人選擇乙個點集,兩個人選的點集不想交,求最大權值 8 21pts 直接暴力列舉 兩個節點不想交 47 65pts 只考慮兩棵樹完全一樣的情況 樹形dp 揹包 dp i j j k dp i j j k dp i j j k 表示以i為跟的子樹,在第一棵樹上選j個,第二棵...