OJ 中的目錄 題解

2021-08-21 06:44:02 字數 3934 閱讀 7187

題目大意:

在一棵樹中選擇k條不重複的垂直的長度在[l

,r] [l,

r]之間的樹鏈,樹鏈的價值定義為點權的加和,求最大總價值 n≤

500000

n

≤500000

顯然,我們可以列舉每一條符合條件的樹鏈,取前k大的進行選擇——極端o(

n∗n)

o (n

∗n)那麼看這題之前,先考慮乙個較簡單的情形:

在乙個陣列中,找乙個第k大的滿足長度為[l

,r] [l,

r]的子串行n≤

500000

n

≤500000

有點困難。。求最大的就很簡單了——

構造字首和,列舉個終點

i i

,在[i

−r,i

−l]' role="presentation" style="position: relative;">[i−

r,i−

l][i

−r,i

−l]中找出最小值,最後刷最優解s[

i]−m

ins [i

]−mi

n:rmq就可以完美搞定了

我們假設mi

n=s[

t]m in

=s[t

],則t t

將區間[i

−r,i

−l]' role="presentation" style="position: relative;">[i−

r,i−

l][i

−r,i

−l]劃分成兩部分,且顯然以

i i

為終點的次優解min一定在區間[i

−r,t

−1]或

[t+1

,i−l

]' role="presentation" style="position: relative;">[i−

r,t−

1]或[

t+1,

i−l]

[i−r

,t−1

]或[t

+1,i

−l]中——

這個問題顯然與剛才的問題相同

那麼,我們就定義乙個三元組(i

,l,r

) (i,

l,r)

,表示從

i i

往左推l−

−r' role="presentation" style="position: relative;">l−−

rl−−

r個單位,即s[

i]−m

in[i

−r][

i−l]

s [i

]−mi

n[i−

r][i

−l]ps:l,r是否包括該元素自己定義,如上為包含的

每次在堆中取個最大的出來,將區間拆分後再放入堆中,處理k次,最後一次的即為答案 效率o

(3∗n

∗log

+n∗l

og預處

理)o (3

∗n∗l

og+n

∗log

預處理)

#pragma gcc optimize(6)

#include

#include

#include

#define ll long long

using namespace std;

const int maxn=(1e5)+5,log=21;

int n,k,l,r,len;ll s[maxn];

templatet min(t a,t b)

void ask(int x,int l,int r)

struct ff

ff get()

char gt()

int read()

int main();

make();

for(int i=l;i<=n;i++) ask(i,l,min(i,r)),put(((ff)));

while(k--)));

if(ans.x-ans.it+2

<=ans.r) ask(ans.x,ans.x-ans.it+2,ans.r),put(((ff)));

}printf("%lld\n",ans.val);

return

0;}

再回歸正題——這題不就是將這個模型做到樹上嗎?

預處理即為樹上rmq——倍增lca的同時順便帶出來就ok了

然後**神似。。

ps:仍然那句話,是否包括自身——下面**中va

l[x]

[i] val

[x][

i]表示節點

x x

向上推了2j

' role="presentation" style="position: relative;">2j2

j個單位(不包括自身)加上自身的價值的最小值(有點拗口?多讀幾遍就懂了o(∩_∩)o!)

#pragma gcc optimize(6)

#include

#include

#define ll long long

using

namespace

std;

const

int maxn=(5e5)+5,log=21;const ll inf=(ll)1

<<60;

int n,m,rot,l,r,len,dep[maxn],down[maxn],up[maxn][log],pow[maxn];ll p[maxn],ans;

template

t min(t a,t b)

char gt()

int read()

struct ff

ff get()

struct st

}val[maxn][log],now;

st getdata(int x,int l,int r)));

now.id=down[now.id];

}void dfs(int x,int fa)),((st))),up[x][0]=fa,down[fa]=x;

for(int i=1;(1

<1]][i-1],val[x][i]=min(val[x][i-1],val[up[x][i-1]][i-1]);

if(dep[x]>=l) getdata(x,min(l,dep[x]),min(r,dep[x])),put(((ff)));

for(int j=lnk[x];j;j=nxt[j]) dfs(son[j],x);

}int main()

for(int i=1;i<=n;i++) p[i]=read();

m=read(),l=read(),r=read();

for(int i=1;i<=maxn-5;i++) pow[i]=pow[i-1]+((1

<

dep[rot]=1,dfs(rot,0);

while(m--)));

if(dep[k.x]-dep[k.it]+2

<=k.r) getdata(k.x,dep[k.x]-dep[k.it]+2,k.r),put(((ff)));

}printf("%lld\n",ans);

return

0;}

九度Oj題解

一 動態規劃專題 1205 n階樓梯上樓問題 dp i 表示到達i階的方法數,狀態轉移方程 dp i dp i 1 dp i 2 值很大要用long long.1451 不容易系列之一 dp i 表示總共i個數時的錯排方案數,狀態轉移方程 dp i i 1 dp i 1 i 2 dp i 2 142...

北大oj題解 2255

根據二叉樹的前序和中序寫出後序 二叉樹比較適合用遞迴的方法,按照需要分別處理根節點和左右子樹,前序串的特點是第乙個字元代表的都是該樹的根節點,中序串的特點是左右子樹分別位於根節點的兩側 同理,後序串的特點是最後乙個字元代表根節點 先處理左右子樹最後訪問根節點可得後序串。include include...

學軍OJ題解 1179 約會

學軍oj,題號1179,鏈結 也可以到 小藍準備去和小紅約會,小藍和小紅居住在乙個平面直角座標系中,小藍的家在 0,0 位置,小紅的家在 a,b 位置,小藍每一步可以往上下左右中的任意乙個方向移動乙個單位,換句話說,他可以從 x,y 走 到 x 1,y x 1,y x,y 1 x,y 1 中的乙個位...