2019集訓隊互測 學習軌跡(貪心)

2021-10-05 00:10:44 字數 2093 閱讀 4529

首先沒有限制的話排個序就完事了。

如果有限制的話,顯然我們需要幹的事情就是做出修正。

按照權值從小到大排序。

考慮什麼情況下非法,權值小的依賴權值大的。

這個時候的修正非常明顯,把這個區間拎出來,無依賴的公升序,然後有依賴的降序排在後面。

這樣的區間可以通過一次差分字首和找出來。

容易注意到有的時候我們把若干個區間合併可以得到更優的答案。

簡單討論可以發現,如果不是全部合併,必然是字首合併一段,中間全部不合併,字尾合併一段,找到這個合併的位置即可。

注意權值從大到小是等價的,我們還要把權值乘上-1再做一遍。

**:

#include

#define ll long long

#define re register

#define cs const

namespace io

template

<

typename t>t get_integer()

inline

intgi()

inline ll gl()

char obuf[

30000007],

*oh=obuf,ch[23]

;template

<

typename t>

void

print

(t a,

char c)

struct obuf_flusher

}flusher;

}using

namespace io;

using std::cerr;

using std::cout;

using pli=std::pairint>

;#define fi first

#define se second

cs int n=

1e6+7;

ll w[n]

;int n,m,bel[n]

;int id[n]

,ps[n]

,l[n]

,r[n]

; ll ans[2]

;int ans[2]

[n];

int sm[n]

;pli f[n]

;void

work

(int o)

;for

(int i=

2;i<=ct;

++i)

f[i]

=std::min(,

);ll tmp=

1e18+7

;int pl=

0,pr=0;

for(

int re i=

1;i++i)

if(ans[o]

>tmp)

for(

int re i=l[pr]

;i<=n;

++i)

if(id[i]

<=m)ans[o]

[++tl]

=id[i]

;for

(int re i=n;i>=l[pr]

;--i)

if(id[i]

>m)ans[o]

[++tl]

=id[i];}

}}void

main()

);work(0

);for(

int re i=

1;i<=n;

++i)w[i]

=-w[i]

; std::

reverse

(id+

1,id+n+1)

;work(1

);bool o=ans[1]

;print

(ans[o]

,'\n');

for(

int re i=

1;i<=n;

++i)

print

(ans[o]

[i],

' ');}

inline

void

file()

signed

main()

主席樹 2012集訓隊互測 Middle

jzoj 2902 集訓隊互測2012 middle 陳立傑 題解 這題雖然不是這幾天做的,但是最近在搞資料結構,再總結一下還是會有收穫的。複習時應該看看 設乙個序列s從大到小排序後為s 1.k 則中位數為m s k 2向上取整 那就意味著,在序列s中,大於等於m的數大於等於k 2。如果把序列s轉化...

集訓隊互測 2012 Attack

description chnlich非常喜歡玩三國志這款遊戲,並喜歡用一些策略出奇制勝。現在,他要開始征服世界的旅途了。他的敵人有n nn座城市和n nn個太守,n nn個城市可以看作在二維平面上的n nn個點。n nn座城市的標號為0,1 2,n 1 0,1,2,cdots,n 1 0,1,2,...

集訓隊互測2015 Robot

題目描述 題解 維護兩顆線段樹,維護最大值和最小值,因為每次只有單點查詢,所以可以直接在區間插入線段就可以了。注意卡常,不要寫stl,用鍊錶把同類修改串起來就好了。pragma gcc optimize 2 pragma gcc optimize 3 include include include ...