品酒大會
【問題描述】
【輸入格式】
【輸出格式】
【樣例輸入】
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 #include7using
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 而乘積最...