題目等價於求任意兩對字尾的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,每個標...