品酒大會 BZOJ 4199

2022-08-21 16:36:09 字數 2332 閱讀 9968

品酒大會

【問題描述】

【輸入格式】

【輸出格式】

【樣例輸入】

10ponoiiipoi

2 1 4 7 4 8 3 6 4 7

【樣例輸出】

45 56

10 56

3 32

0 00 0

0 00 0

0 00 0

0 0【資料範圍】

題解:根據題意可得"r相似」也是「r - 1相似」

那麼我們只要求出了所有最大為 r 相似的對數,就可以利用字尾和求出所有r相似的個數

考慮一瓶酒與另一瓶酒如果是 r 相似的,那麼與其中一瓶酒 k (k > r) 相似的酒與另一瓶酒最大也為 r 相似

所以用字尾陣列求出 height 陣列

然後按 height 從大到小排序

每次按順序找出兩個 height 相似的點的祖先

height 相似的對數累加上兩個祖先塊內的點數乘積

height 相似的最大值為兩個塊的最小值乘積和最大值乘積的較大值

用並查集合並,處理點的個數、最大值和最小值(美味度有負數)

最後跑一遍字尾和

1 #include2 #include3 #include4 #include5 #include6 #include7

using

namespace

std;

8 inline void scan(int &x)918

const

int me = 1000233;19

intn;

20int

w[me];

21int

x[me];

22int

sa[me], he[me];

23int

val[me], fat[me], nex[me];

24int

rank[me];

25long

long

ans_si[me], ans_mx[me];

26char

s[me];

27struct

union28;

31union un[me];

32 inline void

sa()

3356

if(n == m) break;57

for(int i = 1; i <= n; ++i) swap(x[i], rank[i]);58}

59int tot = 0;60

inti, j;

61for(i = 1; i <= n; i ++)

6268

}69 inline bool rule(const

int &x, const

int &y)

7073 inline int find(const

int &x)

7477 inline void un(const

int &x, const

int &y)

7884

intmain()

8594

sa();

95for(int i = 0; i <= n; ++i)

96 ans_mx[i] = -2147483647214748364;97

for(int i = 1; i <= n; ++i)

98 un[i] = (union) ;

99 sort(nex + 1, nex +n, rule);

100for(int i = 1; i < n; ++i)

101108

for(int i = n - 1; i >= 0; --i)

109113

for(int i = 0; i < n; ++i)

114 printf("

%lld %lld\n

", ans_si[i], ans_si[i] ? ans_mx[i] : 0

);115 }

bzoj4199 Noi2015 品酒大會

一年一度的 幻影閣夏日品酒大會 隆重開幕了。大會包含品嚐和趣味挑戰兩個環節,分別向優勝者頒發 首席品酒家 和 首席獵手 兩個獎項,吸引了眾多品酒師參加。在大會的晚餐上,調酒師 rainbow 調製了 n 杯雞尾酒。這 n 杯雞尾酒排成一行,其中第 i 杯酒 1 le i le n 被貼上了乙個標籤 ...

BZOJ4199 NOI2015 品酒大會

一年一度的 幻影閣夏日品酒大會 隆重開幕了。大會包含品嚐和趣味挑戰兩個環節,分別向優勝者頒發 首席品酒家 和 首席獵手 兩個獎項,吸引了眾多品酒師參加。在大會的晚餐上,調酒師rainbow調製了 n 杯雞尾酒。這 n 杯雞尾酒排成一行,其中第 i 杯酒 1 i n 被貼上了乙個標籤 s i 每個標籤...

Noi 2015 品酒大會

題目等價於求任意兩對字尾的lcp的值小於等於1,2 n的個數,以及權值乘積的最大值。求出字尾陣列的height值,然後預處理出每個height值能夠成為最小的區間。考慮每個height的值對答案的貢獻 如果height i 能夠成為最小的區間為 l,r 那麼個數便是 l i 1 r i 1 而乘積最...