一年一度的「幻影閣夏日品酒大會」隆重開幕了。大會包含品嚐和趣味挑戰 兩個環節,分別向優勝者頒發「首席品酒家」和「首席獵手」兩個獎項,吸引了眾多品酒師參加。
在大會的晚餐上,調酒師 rainbow 調製了 n 杯雞尾酒。這 n 杯雞尾酒排成一行,其中第 n 杯酒 (1 ≤ i ≤ n) 被貼上了乙個標籤si,每個標籤都是 26 個小寫 英文本母之一。設 str(l, r)表示第 l 杯酒到第 r 杯酒的 r − l + 1 個標籤順次連線構成的字串。若 str(p, po) = str(q, qo),其中 1 ≤ p ≤ po ≤ n, 1 ≤ q ≤ qo ≤ n, p ≠ q, po − p + 1 = qo − q + 1 = r ,則稱第 p 杯酒與第 q 杯酒是「 r 相似」 的。當然兩杯「 r 相似」(r > 1)的酒同時也是「 1 相似」、「 2 相似」、……、「 (r − 1) 相似」的。特別地,對於任意的 1 ≤ p , q ≤ n , p ≠ q ,第 p 杯酒和第 q 杯酒都 是「 0 相似」的。
在品嚐環節上,品酒師 freda 輕鬆地評定了每一杯酒的美味度,憑藉其專業的水準和經驗成功奪取了「首席品酒家」的稱號,其中第 i 杯酒 (1 ≤ i ≤ n) 的 美味度為 ai 。現在 rainbow 公布了挑戰環節的問題:本次大會調製的雞尾酒有乙個特點,如果把第 p 杯酒與第 q 杯酒調兌在一起,將得到一杯美味度為 ap*aq 的 酒。現在請各位品酒師分別對於 r = 0,1,2, ⋯ , n − 1 ,統計出有多少種方法可以 選出 2 杯「 r 相似」的酒,並回答選擇 2 杯「 r 相似」的酒調兌可以得到的美味度的最大值。
輸入格式:
第 1 行包含 1 個正整數 n ,表示雞尾酒的杯數。
第 2 行包含乙個長度為 n 的字串 s,其中第 i 個字元表示第 i 杯酒的標籤。
第 3 行包含 n 個整數,相鄰整數之間用單個空格隔開,其中第 i 個整數表示第 i 杯酒的美味度 ai 。
輸出格式:
包括 n 行。第 i 行輸出 2 個整數,中間用單個空格隔開。第 1 個整 數表示選出兩杯「 (i − 1)
相似」的酒的方案數,第 2 個整數表示選出兩杯 「 (i − 1) 相似」的酒調兌可以得到的最大美味度。若不存在兩杯「 (i − 1) 相似」
的酒,這兩個數均為 0 。
輸入樣例#1:複製
10輸出樣例#1:複製ponoiiipoi
2 1 4 7 4 8 3 6 4 7
45 56輸入樣例#2:複製10 56
3 32
0 00 0
0 00 0
0 00 0
0 0
12輸出樣例#2:複製abaabaabaaba
1 -2 3 -4 5 -6 7 -8 9 -10 11 -12
66 120【樣例說明 1】34 120
15 55
12 40
9 27
7 16
5 73 -4
2 -4
1 -4
0 00 0
用二元組 (p, q) 表示第 p 杯酒與第 q 杯酒。
0 相似:所有 45 對二元組都是 0 相似的,美味度最大的是 8 × 7 = 56 。
1 相似: (1,8) (2,4) (2,9) (4,9) (5,6) (5,7) (5,10) (6,7) (6,10) (7,10) ,最大的 8 × 7 = 56 。
2 相似: (1,8) (4,9) (5,6) ,最大的 4 × 8 = 32 。
沒有 3,4,5, ⋯ ,9 相似的兩杯酒,故均輸出 0 。
問題轉化為分別求lcp>=r的字尾的組數
lcp為l的一組 對後面的l-1 l-2 l-3....也可以貢獻
求出每個height
實際上對於每個(i,j),他的lcp都應當統計
可以單獨考慮每個height的貢獻
l[i]表示最靠左的不大於它的位置
r[i]表示最靠右的大於它的位置(避免重複計算)
那麼height[i]的貢獻就是(i-l[i]+1)*(r[i]-i+1)
對於第二問,對左右取最大值相乘,再取最小值相乘,用st表
1 #include2 #include3 #include4 #include5 #include6using
namespace
std;
7 typedef long
long
lol;
8 lol ans[300001],sum[300001];9
intn,m;
10 lol min[300001][21],max[300001][21],w[300001
];11
int c[300001],x[300001],y[300001
];12
int sa[300001],rank[300001],s[300001],h[300001],log[300001
];13 lol st[300001],l[300001],r[300001
];14
char ch[300001
];15
void
radix_sort()
16 26
void
build_sa()
27 47
for (i=1;i<=n;i++)
48 rank[sa[i]]=i;
49int l=0;50
for (i=1;i<=n;i++)
5157
}58 lol rmq_max(int x,int
y)59
63 lol rmq_min(int x,int
y)64
68int
main()
6977
for (i=1;i<=n;i++)
7881
build_sa();
82for (i=1;i<=n;i++)
83 min[i][0]=max[i][0]=w[sa[i]];
84for (j=1;(1
8591}92
for (i=1;i<=n;i++)
9399 log[1]=0
;100
for (i=2;i<=n;i++)
101 log[i]=log[i/2]+1
;102 top=0
;103
for (i=n;i>=1;i--)
104110
for (i=0;i<=n;i++)
111 ans[i]=-2e18;
112for (i=1;i<=n;i++)
113118
for (i=n-2;i>=0;i--)
119123 sum[0]=(n-1)*n/2
;124
for (i=0;i<=n-1;i++)
125 printf("
%lld %lld\n
",sum[i],ans[i]==-2e18?0
:ans[i]);
126 }
Noi 2015 品酒大會
題目等價於求任意兩對字尾的lcp的值小於等於1,2 n的個數,以及權值乘積的最大值。求出字尾陣列的height值,然後預處理出每個height值能夠成為最小的區間。考慮每個height的值對答案的貢獻 如果height i 能夠成為最小的區間為 l,r 那麼個數便是 l i 1 r i 1 而乘積最...
NOI2015 品酒大會
字尾自動機 首先考慮第一問 我們先將字尾自動機建出來,考慮每個節點,它出現的次數肯定是endpos的size 我們記為num 那麼選取這個節點的串的方案數即為c num,2 num num 1 2,所能貢獻的長度區間為這個節點對應的所有串的長度即 len fa x 1 len x 1 這裡可以差分一...
NOI2015 品酒大會
一年一度的 幻影閣夏日品酒大會 隆重開幕了。大會包含品嚐和趣味挑戰 兩個環節,分別向優勝者頒發 首席品酒家 和 首席獵手 兩個獎項,吸引了眾多品酒師參加。在大會的晚餐上,調酒師 rainbow 調製了 n 杯雞尾酒。這 n 杯雞尾酒排成一行,其中第 n 杯酒 1 i n 被貼上了乙個標籤si,每個標...