自己尝试敲后缀数组,发现难看(tiao)的不行,于是抄了板子

考虑建出hei以后转化出的问题:

对于一个数组中权值大于等于k的连续部分,求取两个数的方案数和两数积的最大值

(好气啊,可以有负数)

把询问倒序以后相当于连续部分之间会动态加元素,使他们连起来

维护一段极大连续段的最大值、最小值、长度,保存在左右两端——wtf我也不知道这算什么做法

然后瞎**乱搞一下,就能每次合并O(1)维护出来了(似乎没比并查集好多少)

 #include <bits/stdc++.h>
#define N 300001
#define MIN -9223372036854775807
#define calc(x) (x)*((x)-1)/2
#define ll long long
using namespace std;
ll n,ans,ans2;
ll c[N],mi[N],ma[N],len[N],w[N];
ll sa[N],Rank[N],height[N];
ll wa[N],wb[N],wv[N],wd[N];
ll out1[N],out2[N];
struct node
{
ll x,y;
node(ll p,ll q)
{
x=p;y=q;
}
node()
{
}
} t[N];
bool cmp(ll *r,ll a,ll b,ll l)
{
return r[a]==r[b]&&r[a+l]==r[b+l];
}
bool com(node a,node b)
{
return a.x>b.x;
}
void da(ll *r,ll n,ll m)
{
ll *x=wa,*y=wb,*t;
for (ll i=;i<m;i++) wd[i]=;
for (ll i=;i<n;i++) wd[x[i]=r[i]]++;
for (ll i=;i<m;i++) wd[i]+=wd[i-];
for (ll i=n-;i>=;i--) sa[--wd[x[i]]]=i;
for (ll j=,p=,i;p<n;j<<=,m=p)
{
for (p=,i=n-j;i<n;i++) y[p++]=i;
for (i=;i<n;i++) if (sa[i]>=j) y[p++]=sa[i]-j;
for (i=;i<n;i++) wv[i]=x[y[i]];
for (i=;i<m;i++) wd[i]=;
for (i=;i<n;i++) wd[wv[i]]++;
for (i=;i<m;i++) wd[i]+=wd[i-];
for (i=n-;i>=;i--) sa[--wd[wv[i]]]=y[i];
for (t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
}
void get_height(ll *r,ll n)
{
for (ll i=;i<=n;i++) Rank[sa[i]]=i;
for (ll i=,k=,j;i<n;height[Rank[i++]]=k)
for (k?k--:,j=sa[Rank[i]-];r[i+k]==r[j+k];k++);
}
void merge(ll x,ll y)
{
if(!len[x] || !len[y]) return;
ans2+=calc(len[x]+len[y]+)-calc(len[x]+)-calc(len[y]+);
ans=max(ans,w[sa[x-len[x]]]*mi[y]);ans=max(ans,mi[x]*mi[y]);
ans=max(ans,w[sa[x-len[x]]]*ma[y]);ans=max(ans,ma[x]*ma[y]);
ll MI=min(mi[x],mi[y]),MA=max(ma[x],ma[y]);
mi[x-len[x]+]=mi[y+len[y]-]=MI;
ma[x-len[x]+]=ma[y+len[y]-]=MA;
len[x-len[x]+]=len[y+len[y]-]=len[x]+len[y];
}
void add(ll now)
{
if(!now) return;
len[now]=;
mi[now]=ma[now]=w[sa[now]];
ans=max(ans,w[sa[now]]*w[sa[now-]]);
++ans2;
if(now)
merge(now-,now);
if(now<n-)
merge(now,now+);
}
int main()
{
scanf("%lld",&n);
for(ll i=;i<n;i++)
{
char ch;
while(ch=getchar(),!isalpha(ch));
c[i]=ch-'a'+;
}
for(ll i=;i<n;i++)
scanf("%lld",&w[i]);
c[n]=;
da(c,n+,);
get_height(c,n);
for(ll i=;i<n;i++)
sa[i]=sa[i+],height[i]=height[i+];
if()
for(ll i=;i<n;i++)
{
printf("%lld %lld\n",sa[i],height[i]);
}
for(ll i=;i<n;i++)
t[i]=node(height[i],i);
sort(t,t+n,com);
ll j=;
ans=MIN;ans2=;
for(ll i=;i<n;i++)
len[i]=,ma[i]=MIN,mi[i]=-MIN;
for(ll i=n-;i>=;i--)
{
while(j<n && t[j].x==i) add(t[j].y),j++;
out1[i]=ans2;out2[i]=(ans==MIN)?:ans;
}
for(ll i=;i<n;i++)
printf("%lld %lld\n",out1[i],out2[i]);
return ;
}

NOI2015品酒大会 后缀数组的更多相关文章

  1. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  2. [UOJ#131][BZOJ4199][NOI2015]品酒大会 后缀数组 + 并查集

    [UOJ#131][BZOJ4199][NOI2015]品酒大会 试题描述 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个 ...

  3. 【BZOJ4199】[Noi2015]品酒大会 后缀数组+并查集

    [BZOJ4199][Noi2015]品酒大会 题面:http://www.lydsy.com/JudgeOnline/wttl/thread.php?tid=2144 题解:听说能用SAM?SA默默 ...

  4. [NOI2015] 品酒大会 - 后缀数组,并查集,STL,启发式合并

    [NOI2015] 品酒大会 Description 对于每一个 \(i \in [0,n)\) 求有多少对后缀满足 LCP 长度 \(\le i\) ,并求满足条件的两个后缀权值乘积的最大值. So ...

  5. BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )

    求出后缀数组后, 对height排序, 从大到小来处理(r相似必定是0~r-1相似), 并查集维护. 复杂度O(NlogN + Nalpha(N)) ------------------------- ...

  6. BZOJ.4199.[NOI2015]品酒大会(后缀数组 单调栈)

    BZOJ 洛谷 后缀自动机做法. 洛谷上SAM比SA慢...BZOJ SAM却能快近一倍... 显然只需要考虑极长的相同子串的贡献,然后求后缀和/后缀\(\max\)就可以了. 对于相同子串,我们能想 ...

  7. 【学术篇】NOI2015 品酒大会 后缀数组+并查集

    省选前大致是刷不了几道题了... 所以就找一些裸一点的题目练练板子算了= = 然而这题一点都不裸, 也并不怎么好写... 于是就浪费了将近一下午的时间... 然而还不是因为后缀数组板子不熟= = 首先 ...

  8. luoguP2178 [NOI2015]品酒大会(后缀数组做法)

    题意 因为一个\(k\)相似必定为\(k-1,k-2....0\)相似,对于一个\(lcp\)为\(k\)后缀对\((i,j)\),我们只用把它的贡献加在\(k\)的答案上,最后求一个后缀和和后缀ma ...

  9. 【BZOJ-4199】品酒大会 后缀数组 + 并查集合并集合

    4199: [Noi2015]品酒大会 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 436  Solved: 243[Submit][Status] ...

随机推荐

  1. Android 7.1 GUI系统-窗口管理WMS-Surface管理(四)

    Surface的管理 Surface是窗口能真正显示到物理屏幕上的基础,由surfaceflinger管理,可以通过WindowStateAnimator.java中的变量mDrawState来查看每 ...

  2. RQNOJ 514 字串距离:dp & 字符串

    题目链接:https://www.rqnoj.cn/problem/514 题意: 设有字符串X,我们称在X的头尾及中间插入任意多个空格后构成的新字符串为X的扩展串,如字符串X为”abcbcd”,则字 ...

  3. listen 71

    Creepy People Leave You Cold Jack Nicholson, playing the crazed caretaker in The Shining, makes me r ...

  4. Posix线程编程指南(1)

    这是一个关于Posix线程编程的专栏.作者在阐明概念的基础上,将向您详细讲述Posix线程库API.本文是第一篇将向您讲述线程的创建与取消.   一.线程创建 1.1 线程与进程相对进程而言,线程是一 ...

  5. poj 2420 A Star not a Tree?——模拟退火

    题目:http://poj.org/problem?id=2420 精度设成1e-17,做三遍.ans设成double,最后再取整. #include<iostream> #include ...

  6. bzoj 5281 [Usaco2018 Open]Talent Show——0/1分数规划

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=5281 把分子乘1000,就能在整数里做了. 这种水题也花了这么久…… #include< ...

  7. Jmeter查看结果树Unicode编码转中文方法

    本文为转载微信公众号文章,如作者发现后不愿意,请联系我进行删除 在jmeter工具的使用中,不管是测试接口还是调试性能时,查看结果树必不可少,然而在查看响应数据时,其中的中文经常以Unicode的编码 ...

  8. JS---设计简易日历

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. Eclipse+Maven

    http://www.cnblogs.com/alunchen/p/5632497.html

  10. Http协议-URI和资源

    所有东西都有一个标准化的名字,以帮助人们寻找城市中的各种资源.书籍有ISBN号,公交车有线路号,银行账户有账户编码,人有身份证,街道有街道名称.人们告诉图书馆管理员书籍的ISBN号,他即可找出该书籍的 ...