Noi 2015 品酒大會

2021-07-09 02:00:18 字數 1404 閱讀 7540

題目等價於求任意兩對字尾的lcp的值小於等於1,2…n的個數,以及權值乘積的最大值。

求出字尾陣列的height值,然後預處理出每個height值能夠成為最小的區間。

考慮每個height的值對答案的貢獻:如果height[i]能夠成為最小的區間為[l,r],那麼個數便是(l-i+1)*(r-i+1)。而乘積最大值則一定是max[l,i-1]*max[i,r]或者min[l,i-1]*min[i,r](有可能是負數),用rmq預處理一下就可以。

(當時全場200多個人過了這題,而我寫了乙個下午。。。。。跪跪跪)

#include 

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define putarray(a,n) for (int i=1;i<=n-1;i++) printf("%d ",a[i]); printf("%d\n",a[n]);

using

namespace

std;

typedef

long

long ll;

const

int maxn=300005,inf=(1

<<30);

int n,a[maxn],l[maxn],r[maxn]; char str[maxn];

ll ans[maxn],cnt[maxn];

ll gmax(ll a,ll b)

class rmq

mn[i][j]=min(mn[i][j-1],mn[p][j-1]),mx[i][j]=max(mx[i][j-1],mx[p][j-1]);}}

int askmin(int l,int r)

int askmax(int l,int r)

}rmq;

class suffix_array

}void build_height()

if (k) k--; int j=sa[rank[i]-1];

while (str[i+k]==str[j+k]) k++;

height[rank[i]]=k;}}

public:

void init()

void solve()

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

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

}}sa;

int get()

int main()

return

0;}

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,每個標...

NOI2015 品酒大會

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