20200923 SCOI模擬T2(倍增 分塊)

2021-10-09 17:38:35 字數 4154 閱讀 7215

思路:

考場想法

套路拆環成鏈,離散化

對於乙個當前最遠位置 w

ww,貪心的選包含這個位置,覆蓋最遠的人

可以用分塊預處理每個位置的選擇乙個人後下乙個最遠的位置

時間複雜度:o(n

n)

o(n\sqrt n)

o(nn​)

於是對於每個人可以從右端點向後跳,計算跳回左端點的次數

考慮優化

發現和 彈飛綿羊 很像

於是再次分塊,對每個位置預處理跳到下乙個塊的次數,位置

對於每個人從右端點向後跳,計算跳回左端點的次數

時間複雜度:o(n

n)

o(n\sqrt n)

o(nn​)

時間略卡,於是一口氧氣就過了……

正解和我的想法差不多

但是發現每個點跳下乙個點的位置不變

於是倍增維護

s ti

,j

st_st

i,j​

表示從 i

ii 開始選 2

j2^j

2j個人能到達的最遠位置

時間複雜度:o(n

logn

)o(nlogn)

o(nlog

n)**:

mine

#include

using

namespace std;

#define int long long

#define re register

namespace io

char _buf[

1<<21]

;int _pos =-1

;inline

void

flush()

inline

voidpc(

char x)

inline

void

out(

int x)

}// namespace io

using

namespace io;

const

int a =

1e6+5;

int n, m, blo;

int l[a]

, r[a]

;int w[a]

;int cir[a]

, len;

int be[a]

, tag[a]

;int mx[a]

;int c[a]

, to[a]

;inline

void

lsh(

)for

(re int i =

1; i <= len;

++i)

cir[i]

= ans;

}return;}

inline

void

init()

for(re int j = l[i]

; be[j]

== be[l[i]];

++j) mx[j]

=max

(mx[j]

, r[i]);

for(re int j = be[l[i]]+

1; j <= be[r[i]]-

1;++j)

tag[j]

=max

(tag[j]

, r[i]);

for(re int j = r[i]

; be[j]

== be[r[i]

]; j--

) mx[j]

=max

(mx[j]

, r[i]);

}for

(re int i =

1; i <= len;

++i) mx[i]

=max

(mx[i]

, tag[be[i]])

;return;}

inline

void

prepare()

ans++

; pos = mx[pos]

; c[i]

= ans, to[i]

= pos;

}return;}

inline

void

work

(int now)

while

(pos < cir[l[now]])

out(ans),pc

(' ');

return;}

signed

main()

lsh();

blo =

sqrt

(len)

;for

(re int i =

1; i <= len;

++i) be[i]

=(i -1)

/ blo +1;

init()

;prepare()

;for

(re int i =

1; i <= n;

++i)

work

(i);pc(

'\n');

flush()

;return0;

}/*4 82 5

4 76 1

7 3*/

std

#include

using

namespace std;

#define int long long

#define re register

namespace io

char _buf[

1<<21]

;int _pos =-1

;inline

void

flush()

inline

voidpc(

char x)

inline

void

out(

int x)

}// namespace io

using

namespace io;

const

int a =

1e6+5;

const

int loga =30;

int n, m;

struct node

} p[a]

;int lg[a]

;int st[a]

[loga]

;int res[a]

;inline

void

prepare()

for(

int i =

1; i <= lg[

2* n]

; i++

)for

(int j =

1; j +(1

<< i)-1

<=

2* n; j++

) st[j]

[i]= st[st[j]

[i -1]

][i -1]

;return;}

inline

void

work

(int now)

signed

main()

sort

(p +

1, p +

1+ n)

;for

(int i =

1; i <= n; i++

) p[i + n]

.id = p[i]

.id, p[i + n]

.l = p[i]

.l + m, p[i + n]

.r = p[i]

.r + m;

prepare()

;for

(int i =

1; i <= n; i++

)work

(i);

for(

int i =

1; i <= n; i++

)out

(res[i]),

pc(' ');pc

('\n');

flush()

;return0;

}/*4 82 5

4 76 1

7 3*/

某 SCOI 模擬賽 T1 a DP

有 n nn 個單詞,每個單詞出現 c ic i ci 次,現用 與.給單詞編碼,要求任意乙個單詞的編碼不是另乙個的字首。設 的權值為 2,的權值為 1,最小化所有單詞的權值和。n 750 n leq 750 n 750。假設我們已經建好了所有單詞的字典樹,顯然出現次數越多的單詞應該掛在越淺的葉子 ...

20200717 SCOI模擬T1(計數)

description 毒瘤出題人給了你乙個由且僅由小寫字母構成的字串,並且多次詢問你一段區間的字元組成的字串中,noi 子串行出現的次數。輸入輸入資料從noi.in讀入 第一行兩個整數n,m表示字串的長度和詢問次數第二行乙個由小寫字母組成的字串s,下標從1開始標號然後一行乙個整數seed,含義請參...

20200916 SCOI模擬T1(三分)

思路 設怪物的屬性為 a,b a,ba,b,環境值為 x,y x,yx,y t x yt frac t yx 每個怪的貢獻為 a b at b ta b frac b times t a b ta b t發現是乙個單峰函式 打表發現總貢獻也是單峰的,於是可以三分 開口向上的單峰函式的max也是單峰的...