Luogu P2839 國家集訓隊 middle

2022-02-08 22:05:24 字數 1267 閱讀 7725

首先 [b,c] 是必選的, 然後選一段 [a,b) 的字尾和一段 (c,d] 的字首(都可空)。

對於中位數(這裡中位數採用這道題的定義)有個常見的處理方式: 二分 mid, 將 0, 則說明 ≥mid 的佔到了一半以上, 即中位數 ≥mid。

採用這種處理方式, 二分中位數, 由於要中位數盡量大, 所以要貪心, 選字尾和字首使得大於等於 mid 的減去小於等於 mid 的最大。

可以用可持久化線段樹, 具體地, 類似笛卡爾樹, 從小到大插入元素, 找出最大的字首和字尾, 是可並資訊, 可做。

#includeusing namespace std;

const int n = 2e4 + 23, sz = 17 * 2e4 + 233;

int n;

struct seq seq[n];

bool cmp(seq s1, seq s2)

struct dat

dat()

} t[sz];

dat mg(dat lef, dat rig)

int tot, root[n], ls[sz], rs[sz];

void ins(int p, int &q, int l, int r, int x)

ls[q] = ls[p], rs[q] = rs[p];

int mid = (l+r) >> 1;

if(x<=mid)

ins(ls[p], ls[q], l, mid, x);

else

ins(rs[p], rs[q], mid+1, r, x);

t[q] = mg((ls[q]?t[ls[q]]:dat(mid-l+1,-(mid-l+1),0,0)), (rs[q]?t[rs[q]]:dat(r-mid,-(r-mid),0,0)));

}dat ask(int me, int l, int r, int x, int y)

bool chk(int mid, int a, int b, int c, int d)

int sol(int a, int b, int c, int d)

return seq[l].a;

}int main()

, las = 0;

while(q--)

sort(q, q+4);

las = sol(q[0], q[1], q[2], q[3]);

cout << las << '\n';

} return 0;

}

P2839 國家集訓隊 middle

提一下靜態區間第k小的nlog2n的做法 1.建關於排名的主席樹 按排名順序建樹 2.二分答案。這樣做靜態區間第k小的雖然有些zz,但它的意義在於將線段樹 維護的物件改變了。1 include2 using namespace std 3int n,m,cnt 4int a 5 midd 5int ...

Luogu 2839 國家集訓隊 middle

感覺這題挺好的。首先對於中位數最大有乙個很經典的處理方法就是二分,每次二分乙個陣列中的下標 mid 然後我們把 mid 代回到原來的陣列中檢查,如果乙個數 a geq mid 那麼就把 s 記為 1 否則把 s 記為 1 然後對 s 跑一遍字首和,觀察是否有乙個區間的和不小於 0 讀清楚題意之後發現...

luogu P1505 國家集訓隊 旅遊

題面傳送門 第一次一遍過國集紫題。好激動。一看就是樹剖,只不過操作有點多。把每條邊的權值放在兒子節點即可。對於取相反數放懶標記即可。其他是樹剖正常操作。實現 include include define max a,b a b a b define min a,b a b a b using nam...