bzoj4919 Lydsy1706月賽 大根堆

2022-05-10 21:49:07 字數 1482 閱讀 2937

給定一棵n個節點的有根樹,編號依次為1到n,其中1號點為根節點。每個點有乙個權值v_i。

你需要將這棵樹轉化成乙個大根堆。確切地說,你需要選擇盡可能多的節點,滿足大根堆的性質:對於任意兩個點i,j,如果i在樹上是j的祖先,那麼v_i>v_j。

請計算可選的最多的點數,注意這些點不必形成這棵樹的乙個連通子樹。

第一行包含乙個正整數n(1<=n<=200000),表示節點的個數。

接下來n行,每行兩個整數v_i,p_i(0<=v_i<=10^9,1<=p_i輸出一行乙個正整數,即最多的點數。

63 0

1 12 1

3 14 1

5 1

1 #include2 #include3 #include4 #include5 #include6

using

namespace

std;

7struct

node

8edge[400001

];11

int num,head[200001],c[20000001],ch[20000001][2],flag,pos,root[200001],n,a[200001],b[200001

];12

void add(int u,int

v)13

19void pushup(int

rt)20

23int merge(int a,int

b)24

33void del(int rt,int l,int

r)34

41int mid=(l+r)/2;42

if (c[ch[rt][0]]) del(ch[rt][0

],l,mid);

43else del(ch[rt][1],mid+1

,r);

44pushup(rt);45}

46void update(int &rt,int l,int r,int

x)47

54int mid=(l+r)/2;55

if (x<=mid)

5660

else

61 update(ch[rt][1],mid+1

,r,x);

62pushup(rt);63}

64void dfs(int

x)65

72 flag=0

;73 update(root[x],1

,n,a[x]);74}

75int

main()

76 86 sort(b+1,b+n+1

);87 sz=unique(b+1,b+n+1)-b-1;88

for (i=1;i<=n;i++)

89 a[i]=lower_bound(b+1,b+sz+1,a[i])-b;

90 dfs(1

);91 cout<1

]];92

}93

BZOJ4919 Lydsy六月月賽 大根堆

題解 我覺得資料結構寫成結構體還是有必要的 因為不然一道題裡出現了兩個相同的資料結構由於名字很像很容易出錯 另外初始化用segmenttree 首先裸的dp很好想 f i j 表示在i點,最大值 j的點數最大值 看了別人的題解知道了可以用線段樹合併來優化這個東西。我們考慮對於每個點,首先我們要合併它...

題解 BZOJ4919 大根堆

題面 傳送門。老師說今天要考一道線段樹合併,然後。然後這道題我就gg了。當然可以用線段樹合併寫,只是比較複雜 有人賽時想了個貪心,然後被機房巨佬hack了,結果在hack的過程中巨佬想出了正解。貪心思路 對於乙個節點,取右邊的 大一點的 肯定更優。其實很好hack啊,隨便搞一條鏈就可以了 ac思路 ...

BZOJ4919 大根堆 樹上LIS

題目描述見鏈結 樹上 lis lisli s 問題,使用std multisetst維護當前子樹內所有可能的 lis lisli s 結尾,從前往後 lis lisli s結尾 對應的長度遞增 子樹之間互不影響,只需考慮子樹根節點 u uu 對子樹內的影響,模擬 序列lis lisli s 的做法,...