LINK:波波老师

LINK:同bzoj 1396 识别子串

不过前者要求线性做法 后者可以log过。实际上前者也被我一个log给水过了.

其实不算很水 我自认跑的很快罢了.

都是求经过一个位置的最短的 在整个字符串中只出现过一次的子串。

SAM很容易完成这个东西.

考虑对于计算每个节点的贡献 容易发现是一个区间整体赋值和一个等差数列 不过太懒了不想维护这个等差数列 我反着建SAM维护最右左端点了。

就变成了两个区间最值问题。完全可以标记永久化 可能有点卡空间。

当然考场上也思考了O(n)的做法 先考虑等差数列那个地方 由于right集大小为1 那么显然这个点的len是一直到之后都有效所以可以直接标记最后取max

考虑区间取min操作。当时想法是排序后利用并查集 排列可以利用桶排 然后复杂度就降到\(n\cdor (a)\)

可以发现桶排序之后可以利用单调队列+链表 来实现O(n).细节有点繁琐 不再赘述.

标记永久化还是很快滴 (比其他dalao写zkw线段树要快一点.当时我也想写zkw线段树 不过不太熟练所以就没用

const int MAXN=5000010;
int n,cnt=1,last=1;
int sum[MAXN<<2],w[MAXN<<2];//一个取max 一个取min.
struct wy
{
int ch[5];
int fa,len;
}t[MAXN<<1];
char a[MAXN];ll ans;
int c[MAXN],vis[MAXN<<1],s[MAXN<<1];
inline void insert(int x)
{
int p=last;
int np=last=++cnt;
len(np)=len(p)+1;
while(p&&!t[p].ch[x])
{
t[p].ch[x]=np;
p=f(p);
}
if(!p)f(np)=1;
else
{
int q=t[p].ch[x];
if(len(q)==len(p)+1)f(np)=q;
else
{
int nq=++cnt;
t[nq]=t[q];
len(nq)=len(p)+1;
f(np)=f(q)=nq;
while(p&&t[p].ch[x]==q)
{
t[p].ch[x]=nq;
p=f(p);
}
}
}
}
inline void topsort()
{
rep(1,cnt,i)++c[len(i)];
rep(1,n,i)c[i]+=c[i-1];
rep(1,cnt,i)s[c[len(i)]--]=i;
}
inline void change(int p,int l,int r,int L,int R,int x)
{
if(l==L&&r==R)return sum[p]=min(sum[p],x),void();
int mid=(l+r)>>1;
if(L>mid)return change(yy,mid+1,r,L,R,x),void();
if(R<=mid)return change(zz,l,mid,L,R,x),void();
change(zz,l,mid,L,mid,x);change(yy,mid+1,r,mid+1,R,x);
}
inline void modify(int p,int l,int r,int L,int R,int x)
{
if(l==L&&r==R)return w[p]=max(w[p],x),void();
int mid=(l+r)>>1;
if(L>mid)return modify(yy,mid+1,r,L,R,x),void();
if(R<=mid)return modify(zz,l,mid,L,R,x),void();
modify(zz,l,mid,L,mid,x);modify(yy,mid+1,r,mid+1,R,x);
}
inline void dfs(int p,int l,int r,int S,int W)
{
S=min(S,sum[p]);W=max(W,w[p]);
if(l==r)
{
if(W==0)W=-INF;
ans+=min(S,l-W+1);
return;
}
int mid=(l+r)>>1;
dfs(zz,l,mid,S,W);
dfs(yy,mid+1,r,S,W);
}
int main()
{
freopen("bobo.in","r",stdin);
freopen("bobo.out","w",stdout);
gc(a);n=strlen(a+1);
fep(n,1,i)insert(a[i]-'a'),vis[last]=i;
topsort();
memset(sum,0x3f,sizeof(sum));
fep(cnt,2,i)
{
int x=s[i];
//cout<<vis[x]<<' '<<len(x)<<endl;
if(vis[x]==-1)vis[f(x)]=-1;
else
{
if(!vis[f(x)])vis[f(x)]=vis[x];
else vis[f(x)]=-1;
}
if(vis[x]!=-1)
{
change(1,1,n,vis[x],vis[x]+len(f(x)),len(f(x))+1);
modify(1,1,n,vis[x]+len(f(x)),vis[x]+len(x)-1,vis[x]);
}
}
dfs(1,1,n,INF,0);putl(ans);
return 0;
}

5.29 省选模拟赛 波波老师 SAM 线段树 单调队列 并查集的更多相关文章

  1. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  2. 6.29 省选模拟赛 坏题 AC自动机 dp 图论

    考场上随手构造了一组数据把自己卡掉了 然后一直都是掉线状态了. 最后发现这个东西不是subtask -1的情况不多 所以就没管无解直接莽 写题有点晚 故没调出来.. 考虑怎么做 容易想到建立AC自动机 ...

  3. 5.29 省选模拟赛 树的染色 dp 最优性优化

    LINK:树的染色 考场上以为这道题要爆蛋了 没想到 推出正解来了. 反正是先写了爆搜的 爆搜最近越写越熟练了 容易想到dp 容易设出状态 f[i][j]表示以i为根的子树内白色的值为j此时黑色的值怎 ...

  4. 3.29省选模拟赛 除法与取模 dp+组合计数

    LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采 ...

  5. 4.9 省选模拟赛 划分序列 二分 结论 树状数组优化dp

    显然发现可以二分. 对于n<=100暴力dp f[i][j]表示前i个数分成j段对于当前的答案是否可行. 可以发现这个dp是可以被优化的 sum[i]-sum[j]<=mid sum[i] ...

  6. 6.18 省选模拟赛 字符串 LCT SAM

    LINK:字符串 看起来很难做 考虑一种暴力 建立SAM后每次查询暴力扫儿子. 期望得分10分.实际得分10分. 另外一种发现每次扫儿子过于暴力 可以每次儿子向上做贡献 每次都暴力向上跳. 期望得分1 ...

  7. 4.24 省选模拟赛 欧珀瑞特 主席树 可持久化trie树

    很容易的一道题目.大概.不过我空间计算失误MLE了 我草草的计算了一下没想到GG了. 关键的是 我学了一个dalao的空间回收的方法 但是弄巧成拙了. 题目没有明确指出 在任意时刻数组长度为有限制什么 ...

  8. 2018-8-10 模拟赛T3(可持久化线段树)

    出题人说:正解离线按DFS序排序线段维护区间和 但是对于树上每个点都有一个区间和一个值,两个点之间求1~m的区间和,这不就是用可持久化线段树吗. 只不过这个线段树需要区间修改,不过不需要标记下传,询问 ...

  9. 7.18 NOI模拟赛 因懒无名 线段树分治 线段树维护直径

    LINK:因懒无名 20分显然有\(n\cdot q\)的暴力. 还有20分 每次只询问一种颜色的直径不过带修改. 容易想到利用线段树维护直径就可以解决了. 当然也可以进行线段树分治 每种颜色存一下直 ...

随机推荐

  1. 平常我们是如何区分css中class和id之间有什么区别的?

    我们平常在用DIV+CSS制作html网页页面时,常会用到class 和id来选择调用CSS样式属性.对学习CSS的新手来说class和id可能比较模糊,同时不知道什么时候该用class,什么时候又用 ...

  2. CF1292C Xenon's Attack on the Gangs 题解

    传送门 题目描述 输入格式 输出格式 题意翻译 给n个结点,n-1条无向边.即一棵树.我们需要给这n-1条边赋上0~ n-2不重复的值.mex(u,v)表示从结点u到结点v经过的边权值中没有出现的最小 ...

  3. 记一次在Grafana中使用Worldmap Panel的经历

    背景 因与工作相关,以下内容皆做了脱敏处理 主要的需求是要根据地理位置查看可视化的数据. 安装及创建 安装命令来源于官网 grafana-cli plugins install grafana-wor ...

  4. Python并发编程——多线程与协程

    Pythpn并发编程--多线程与协程 目录 Pythpn并发编程--多线程与协程 1. 进程与线程 1.1 概念上 1.2 多进程与多线程--同时执行多个任务 2. 并发和并行 3. Python多线 ...

  5. Spring源码解析——核心类介绍

    前言: Spring用了这么久,虽然Spring的两大核心:IOC和AOP一直在用,但是始终没有搞懂Spring内部是怎么去实现的,于是决定撸一把Spring源码,前前后后也看了有两边,很多东西看了就 ...

  6. java 数据结构(一):java常用类 一 String类

    java.lang.String类的使用1.概述String:字符串,使用一对""引起来表示.1.String声明为final的,不可被继承2.String实现了Serializa ...

  7. 数据分析05 /pandas的高级操作

    数据分析05 /pandas的高级操作 目录 数据分析05 /pandas的高级操作 1. 替换操作 2. 映射操作 3. 运算工具 4. 映射索引 / 更改之前索引 5. 排序实现的随机抽样/打乱表 ...

  8. CSS之Bootstrap(快速布局)

    简介 什么是Bootstrap? Bootstrap官网 框架:库 lib library jQuery作为一个框架来讲,提供一套比较便捷的操作DOM的方式 把大家都需要的功能预先写好到一些文件 这就 ...

  9. dataframe一次小实验

    老师搞不清,一个ndarray[df['columns']==a],返回的是什么,目前看来应该是df[] == a 的索引

  10. SpringBoot2.x入门:使用CommandLineRunner钩子接口

    前提 这篇文章是<SpringBoot2.x入门>专辑的第6篇文章,使用的SpringBoot版本为2.3.1.RELEASE,JDK版本为1.8. 这篇文章主要简单聊聊钩子接口Comma ...