構造題訓練

2022-06-03 09:24:11 字數 3157 閱讀 9947

由於noip之前沒有怎麼做過構造,導致吃了大虧。

構造(互動)基本問題:

有一些數,假設有\(n\)個,有\(m\)個被標記,我們可以詢問乙個集合。我們可以得知這個集合內是否存在被標記的數。

要求次數\(o(m\log_2n)\)

做法1:分治

考慮分治到當前區間\([l,r]\),詢問\([l,r]\)有沒有被標記的數。

如果沒有,則返回,否則繼續分治。

時間複雜度等於所有被標記的數到根的鏈的並,是\(o(m\log_2n)\)級別的。

做法2:二分。

按照編號序\(1...n\)進行二分。每次點亮乙個字首,二分出乙個最大的\(l\)使得\([1...l]\)不存在被標記的數。

則\(l+1\)肯定會被標記。

然後把\([1,l+1]\)截掉後繼續二分。

操作次數是\(o(m\log_2n)\)級別的

構造例題1:製作菜品

考場上最後1h才發現此題結論,然後沒寫完。

題目中\(m \geq n-1\)的部分分占比小,\(m=n-2\)的部分分占比巨大。

由於二元關係,可以想到把菜餚連邊。

當\(m=n-2\),我們會發現連出的邊會形成至少\(2\)個連通塊。這是因為每插入一條邊就會減少乙個連通塊。

我們會發現至少有乙個連通塊滿足邊數小於點數,即邊數等於點數\(-1\)。

這樣子我們就轉化為了\(m=n-1\)的情況。

當\(m=n-1\),wlog把\(d\)排序,由於抽屜原理\(d_1

可以證明\(d_1+d_n\geq k\)。

使用反證法。假設\(d_1+d_n\leq k-1,d_n\leq k-1-d_1\)

\(d_1+...d_n\leq (n-1)(k-1-d_1)=(n-1)k-(n-1)-(n-2)d_1<(n-1)k\),矛盾。

然後可以把第乙個材料消掉,\(m--,n--\)。

當\(m\geq n\)由抽屜原理,\(d_n\geq k\),所以把\(d_n-=k\)即可把\(m--\)。

可以用set維護。

當\(m=n-2\)時可以使用dp尋找\(d\)的和等於\((|s|-1)k\)的集合\(s\)。

顯然這是個經典的揹包問題。可以用bitset優化。

考慮把所有物品的重量減去\(k\),就不用記錄選擇了多少個數。

例題2:新年的dog劃分

考慮生成樹。

考慮bfs生成樹,設生成樹當前集合為\(s\),外集合為\(t\)。

每次把乙個點拓展一下。

找到這個點往外連出且沒有被訪問過的點。

然後把這個點往外的邊全部拿出來,把\(s->t\)邊全部刪除,二分出最後乙個插入後仍然不連通的點\(x\)

則\(x->a[x+1]\)(其中\(a\)為二分序列)有邊。

然後把\(x->a[x+1]\)插入佇列。

這樣子重複\(n\)次就得到了乙個生成樹。

判定生成樹合法可以只保留生成樹,刪除生成樹上每一條邊,判定\(n-1\)次。

如果我們刪除某條邊後圖仍然連通,則圖中有奇環,否則沒有。

例題3:i君的商店

先考慮sub4做法。

由於題目給定了\(0/1\)個數的奇偶性,所以考慮把陣列分成長度為\(2\)的塊。

發現每個塊內只可能是全\(0\)或者全\(1\)。

發現不能兩兩比較,所以考慮拿出三個比較。

由於題目中給定最大值為\(1\),所以考慮把\(1\)作為\(t\)集合,每個塊作為\(s\)集合。

如果當前塊比\(1\)小,則塊內的數都是\(0\),否則都是\(1\)。

這樣子我們就可以快速確定乙個塊內元素的值。

可以以這個為依據二分。

前面\(3\)個sub,發現題目的操作如果\(card(s),card(t)=1\),則我們等同於比較整數。

這樣子我們可以使用這個操作把所有數排序再使用sub4的演算法。

這樣子就有76分了。

考場上拿到76分就知足了。

我們真的要把所有整數排序嗎?

考慮兩個數\(x,y\),前面提到,我們可以花費\(2\)的代價找到它們的順序。

根據sub4的做法考慮比較\(x+y,1\)的值。

如果返回\(<\),則\(x+y\leq 1\)否則\(x+y \geq 1\)

由於\(x,y\geq 1\)我們會發現,當返回\(<\)時,\(x,y\)最小者必定等於\(0\)。

否則\(x,y\)最大者必定等於\(1\)。

這樣子我們可以花費\(7\)的代價確定乙個數的值。

但是我們並沒有利用sub4的做法。

根據sub4的做法,隨便拿出兩個數\(x,y\)和\(z\)比較,花費2代價令\(x

如果返回\(<\),則根據前面的分析\(x\)必定等於\(0\)。

否則分類討論可得\(y\geq z\)。

維護乙個有序序列\(s\),把\(y\)插入\(s\)的末尾。

最後會剩下乙個數,可以在\(s\)上二分插入這個數。

然後在\(s\)上二分即可得到所有數的值。

例題4:apio gap

sub1由於次數是\(n/2\),並且每次可以確定兩個值。

考慮每次確定\(a_i,a_\)

呼叫題目給的函式\(minmax(a_i+1,a_-1)\)即可求出\(a_,a_\)的值。

對於sub2考慮抽屜原理。

把\(a_n-a_1\)視為\(a_n-a_1\)個物品。\(a_i-a_\)視為乙個抽屜。

則肯定有乙個抽屜包含至少\(\frac\)個物品。

考慮把陣列分成大小為\(\frac\)的塊。

先呼叫一下\(minmax\)函式求出\(a_n-a_1\)的值以確定塊大小。

發現我們的答案一定不會出現在同一塊內。且只有塊內的最大/最小值有資格成為答案的兩端點。

記錄以前的最大值即可求出答案。

例題5:uoj504

例題6:loj3332

例題7:loj 2875

顯然直接按照\(\min,\max\)的定義進行比較,操作次數為\(o(2n)\)

考慮這麼乙個事實:我們把陣列分成長度為\(2\)的塊,塊內比較一下。

設塊內較小數為\(m1\),較大數為\(m2\),則只有\(m1\)集合內的數可能成為最小值,\(m2\)集合內可能成為最大值。

我們只需要把\(m1\)的數提取出來,\(m2\)的數也提取出來。

把這兩組每組\(n/2\)個數進行比較即可求出最大/最小值。

排序 構造題

題意 給出一段包含 a t g c 的序列,每個字母可以和左右字母交換位置,每次交換造成乙個消耗,構造出 a t g c 分別連續的序列,求出最小的消耗。解析 首先列舉24種可能,即 a t g c 的排列順序,統計每種可能的消耗。對於求每種情況的消耗,需要乙個類似於求逆序數的思想。假設求atgc的...

序列 構造題

首先 最多有乙個數字同時出現在最長上公升子串行和最長下降子串行中,所以若 a b n 1a b n 1,說明無解.然後考慮怎麼構造,將 分成若干個大小為 b b 的塊 可能會剩下乙個小塊 總共有 a nb a bn 個塊,則最長上公升子串行的長度至少為 a a,若 a a,說明無解.否則可以在塊內反...

pytorch批訓練資料構造

這是對莫凡python的學習筆記。1.建立資料 import torch import torch.utils.data as data batch size 8x torch.linspace 1,10,10 y torch.linspace 10,1,10 可以看到建立了兩個一維資料,x 1 1...