Jzoj P4270 魔道研究

2021-08-21 09:57:54 字數 4397 閱讀 1047

有若干個可重集合,然後我們從第

i i

個可重集合中拿前

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

i大組成乙個新的可重集合

s s

。我們的目的是動態維護

s' role="presentation" style="position: relative;">s

s的前

n n

大的和。

給出數n

' role="presentation" style="position: relative;">nn,有

m m

次操作,每次會插入乙個數

p' role="presentation" style="position: relative;">p

p進入集合

t t

中或者在集合

t' role="presentation" style="position: relative;">t

t中刪去原有的乙個數

p p

,然後回答

s' role="presentation" style="position: relative;">s

s中的前

n n

大的和,不足

n' role="presentation" style="position: relative;">n

n時直接求當前

s s

的總和。

1<=t,

n,m<=

300000,1

<=

p<=

1000

000000

' role="presentation" style="position: relative;">1

<=t,

n,m<=

300000,1

<=

p<=

1000

000000

1<=t,

n,m<=

300000,1

<=

p<=

1000

000000

我們可以維護所有的小集合以及

s s

。 維護t

' role="presentation" style="position: relative;">t

t棵權值線段樹,第

i i

棵線段樹對應第

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

i個小集合,

另外維護一棵權值線段樹,對應

s s

。 對於插入操作,即在樹

t' role="presentation" style="position: relative;">t

t中插入

p p

。 可以通過線段樹o(

log' role="presentation" style="position: relative;">o(l

ogo(

logn

) n

)的進行單點修改

然後,

對於要不要將

p p

加入 s 中。

這個只要知道

p' role="presentation" style="position: relative;">p

p在集合

t t

中排名是否

>

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

>第t

t

大, 而對於第

t' role="presentation" style="position: relative;">t

t大,我們也可以通過線段樹得到

然後我們判斷

p p

如果>

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

>第t

t

大,那麼插入進

s' role="presentation" style="position: relative;">s

s中,並將原先在

s s

的集合t' role="presentation" style="position: relative;">tt的第

t t

大的數彈出。

然後對於所有的線段樹,我們都要動態開節點,也就是說我們不把那些空節點建起來,只保留那些非空的節點。ps

:' role="presentation" style="position: relative;">ps:

ps:[

l,r]

[ l,

r]

上,我們要求權值在這個區間裡的第

k k

大元素。 ①l

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

l=r,顯然直接得到為

l l

。 ②l

<

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

<

r,我們可以先看一看這個點的右兒子[m

id+1

,r] [mi

d+1,

r]

。 若[

mid+

1,r]

[ mi

d+1,

r]

中元素個數 ≥k

k,那第

k k

大元素顯然在[m

id+1

,r]' role="presentation" style="position: relative;">[mi

d+1,

r][m

id+1

,r]中,在右兒子求解。 若[

mid+

1,r]

[ mi

d+1,

r]

中的元素個數

<

k <

k,那麼第 k 大元素顯然在[l

,mid

] [l,

mid]

,那麼我們令

k k

減去[m

id+1

,r]' role="presentation" style="position: relative;">[mi

d+1,

r][m

id+1

,r]中的元素個數,減完後的

k k

設為x' role="presentation" style="position: relative;">xx,

那麼我們現在就是要求[l

,mid

] [l,

mid]

中的第x x

大,那麼我們在左兒子求解。

#include

#include

#include

#include

#define fo(i, j, k) for (int i = j; i <= k; i++)

#define n 300005

#define m 50

using

namespace

std;

const

int inf = 1e9;

typedef

long

long ll;

int n, m, tot, root[n], num[n*m], lson[n*m], rson[n*m];

ll ans,sum[n*m];

char s[10];

void insert(int &x, int l, int r, ll k, bool flag)

int get_ranknum(int x, int l, int r, int k)

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

if (num[rson[x]] >= k)

return get_ranknum(rson[x], mid+1, r, k);

ans += sum[rson[x]];

return get_ranknum(lson[x], l, mid, k - num[rson[x]]);

}int main()

else

ans = 0;

get_ranknum(root[0], 0, inf, n);

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

}return

0;}

4 27學習日誌

最近這兩天開運動會了,開運動會這兩天聽課,然後又與週末連在了一起,所以像我這樣沒有運動專案的人就是相當於放了三天假期,明天還有acm的課。上乙個搜尋專題的作業已經截至了,所以想把深度優先搜尋和廣度優先搜尋進行總結一下。其中有的一部分是在網上看的一些介紹的資料。深度優先搜尋 深度優先搜尋法有遞迴以及非...

開發日誌 4 27

除錯記錄 問題 1 當人物處於跳躍狀態時,不應當衰減水平速度velocity.x,如果衰減了這個值,那麼遊戲人物就會很快的停下來,水平位移很小。2 遊戲的速度資料是從下乙個狀態中得到的,並且強制為這個值,那麼就導致遊戲人物的狀態和上乙個狀態無關,顯得很不自然,比如,走動 跳躍,因為跳躍的x速度是零,...

工作日誌4 27

工作日誌4 27 1 討論共享問題,表結構問題 2 總結資料庫建表的幾個重要原則 1 原始單據與實體之間的關係 可以是一對 一 一對多 多對多的關係。在一般情況下,它們是一對一的關係 即一張原始單據對應且只對應乙個實體。在特殊情況下,它們可能是一對多或多對一的關係,即一張原始單證對應多個實體,或多張...