藍橋歷年試題 套娃

2022-03-16 16:57:34 字數 2720 閱讀 2602

作為 drd 送的生日禮物,atm 最近得到了乙個俄羅斯娃娃。他對這個俄羅斯娃娃的構造很感興趣。

俄羅斯娃娃是一層一層套起來的。假設:乙個大小為 x 的俄羅斯娃娃裡面可能會放任意多個大小小於 x 的俄羅斯娃娃(而市場上的套娃一般大娃裡只能放乙個小娃)。

drd 告訴 atm ,這個俄羅斯娃娃是由 n 個小娃娃組成的,它們的大小各不相同。 我們把這些小娃娃的大小從小到大依次記為 1 到 n 。

如果 atm 想觀賞大小為 k 的小娃娃,他會先看這個小娃娃是否已經在桌子上了。 如果已經在桌子上,那麼他就可以觀賞了。否則他就開啟桌子上某乙個俄羅斯娃娃,將它套住的所有的小娃娃拿出來,擺在桌子上。

一開始桌子上只有 drd 送的大小為 n 的娃娃。注意,他只會將其中所有小娃娃拿出來,如果小娃娃裡面還套著另外的小娃娃,他是不會將這些更裡層的這些小娃娃拿出來的。

而且 atm 天生具有最優化的強迫症。他會最小化他所需要開啟的娃娃的數目。

atm 是乙個怪人。有時候他只想知道**大小為 x 的娃娃時需要開啟多少個娃娃(但並不去開啟);有時候聽 drd 說某個娃娃特別漂亮,於是他會開啟看。現在請你輸出他每次需要開啟多少個娃娃。

【輸入格式】

第一行兩個數 n m ,表示娃娃的數目以及 atm 想看的娃娃的數目。

接下來 n - 1 行,每行兩個數 u v,表示大小為 u 的娃娃裡面套著乙個大小為 v 的娃娃。保證 u > v 。

接下來 m 行,每行形如:

p x :表示 atm 一定要看到大小為 x 的娃娃;

q x :表示 atm 只想知道為了看大小為 x 的娃娃,他需要開啟多少個娃娃,但實際上並不開啟他們。

【輸出格式】

輸出 m 行。對應輸入中p操作或q操作需要開啟(或假想開啟)多少個俄羅斯娃娃。

【樣例輸入】

5 55 3

5 43 2

3 1q 1

q 4p 2

q 1q 4

【樣例輸出】21

200【資料範圍】

對於 30% 的資料:n, m <= 1000

對於 100% 的資料:n, m <= 100000

這題想到思路實現後提交一直不對,在搞到後台資料後發現資料出錯了。不知道我打的程式對不對,不過思路我覺得應該就是這樣,畢竟是和qducxk討論出來的。

首先可以看出,資料建出來是一棵樹,然後q就是看這個節點的層數(預設根節點層數是0),然後p無非就是拆樹,從x點開始往上找到最上面的節點,然後把它相連的邊都拆掉,然後再向下更新子樹,在更新子樹這裡如果每次都再跑一遍樹的話,肯定會超時的,我們就想到了樹上的區間修改,那就是記錄下dfs序,然後拆掉這個點就是對子樹的節點層數都-1,因為每條邊只能被拆一次,更新又是nlogn,所以時間複雜度肯定是可以的。

1 #include2

#define l(x) (x<<1)

3#define r(x) (x<<1|1)

4#define m(x) ((t[x].l+t[x].r)>>1)

5const

int n=200118;6

struct

sides[n];

9struct

treet[n<<2

];12

char op[3

];13

int sn,tid,head[n],fa[n],num[n],in[n],out

[n],nid[n];

14void init(int

n)15

20void add(int u,int

v)21

26void dfs(int

u)27

38out[u]=tid;39}

40void built(int id,int l,int

r)41

49built(l(id),l,m(id));

50 built(r(id),m(id)+1

,r);51}

52void down(int

id)53

58void updata(int id,int l,int r)//

區間懶標記更新

5965

if(t[id].lazy)

66down(id);

67if(l<=m(id))

68updata(l(id),l,r);

69if(r>m(id))

70updata(r(id),l,r);71}

72int query(int id,int pos)//

單點查詢 73

80if

(t[id].lazy)

81down(id);

82if(pos<=m(id))

83return

query(l(id),pos);

84else

85return

query(r(id),pos);86}

87void dfs1(int

u)88

98 head[u]=-1;99

out[u]=in

[u];

100}

101int

main()

102111 num[n]=fa[n]=0

;112

dfs(n);

113 built(1,1

,n);

114while(m--)

115121

return0;

122 }

套中套

初見藍橋 歷年試題 最大子陣

歷屆試題 最大子陣 時間限制 1.0s 記憶體限制 256.0mb 問題描述 給定乙個n m的矩陣a,求a中的乙個非空子矩陣,使這個子矩陣中的元素和最大。其中,a的子矩陣指在a中行和列均連續的一塊。輸入格式 輸入的第一行包含兩個整數n,m,分別表示矩陣a的行數和列數。接下來n行,每行m個整數,表示矩...

藍橋杯 歷年試題 矩陣翻硬幣

最近報名了藍橋杯,應該是我學習程式設計以來的第一場正式比賽了,最近就刷了一下歷年試題 這是其中比較有趣的題目,不過我的答案只有70 的分,想看正確 可以看這裡,沒過是演算法不太行,思路還是可以看看的。小明先把硬幣擺成了乙個 n 行 m 列的矩陣。隨後,小明對每乙個硬幣分別進行一次 q 操作。對第x行...

藍橋杯歷年試題 矩陣翻硬幣

問題描述 小明先把硬幣擺成了乙個 n 行 m 列的矩陣。隨後,小明對每乙個硬幣分別進行一次 q 操作。對第x行第y列的硬幣進行 q 操作的定義 將所有第 i x 行,第 j y 列的硬幣進行翻轉。其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。當小明對所有硬幣都進行了一次 q 操作後,他...