博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【LGP5161】WD与数列
阅读量:4676 次
发布时间:2019-06-09

本文共 2666 字,大约阅读时间需要 8 分钟。

也是可以用\(SAM\)来做的

我们发现要求原串不相交,那么就要求在差分序列里不相交并且不相邻

考虑一下\(SAM\),暴力做法自然是对每一个节点统计其所有\(endpos\)的影响

既然这样我们为什么不直接启发式合并加线段树合并分类讨论一下呢

于是可休闲了

我们考虑往一个节点里插入一个新的\(endpos\)会产生什么影响

  1. 对于那些\(x-endpos>=mxlen+1\)\(x\),我们这样插入显然是会产生\(x\)的贡献

  2. 如果\(x-endpos<mxlen+1\),那么就会产生\(|x-enspos|-1\)的贡献

分情况讨论一下这些贡献就好了

于是同时维护动态开点线段树就好了,合并直接线段树合并

代码

#include
#include
#include
#include
#include
#include
#define re register#define LL long long#pragma GCC optimize(3)#pragma GCC optimize("-fcse-skip-blocks")#pragma GCC optimize("Ofast,no-stack-protector")const int maxn=6e5+5;const int R=2e5+5;const int M=2.2e7;using namespace std::tr1;inline int read() { char c=getchar();int x=0,r=1; while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();} while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return r*x;}int n,cnt=1,lst=1,tot,tax[maxn>>1],A[maxn];unordered_map
son[maxn];int len[maxn],fa[maxn];std::vector
pos[maxn];int a[maxn>>1];int rt[maxn],l[M],r[M],t[M];int st[maxn>>1],top;LL d[M],ans,D,T;int change(int now,int x,int y,int pos) { if(!now) { if(!top) now=++tot; else now=st[top--]; } t[now]++,d[now]+=pos; if(x==y) return now; int mid=x+y>>1; if(pos<=mid) l[now]=change(l[now],x,mid,pos); else r[now]=change(r[now],mid+1,y,pos); return now;}LL ask(int now,int x,int y,int lx,int ry) { if(!now||x>y) return 0; if(x<=lx&&y>=ry) return t[now]; int mid=lx+ry>>1; if(y<=mid) return ask(l[now],x,y,lx,mid); if(x>mid) return ask(r[now],x,y,mid+1,ry); return ask(l[now],x,y,lx,mid)+ask(r[now],x,y,mid+1,ry);}void query(int now,int x,int y,int lx,int ry) { if(!now||x>y) return; if(x<=lx&&y>=ry) {T+=t[now],D+=d[now];return;} int mid=lx+ry>>1; if(x<=mid) query(l[now],x,y,lx,mid); if(y>=mid+1) query(r[now],x,y,mid+1,ry);}inline void ins(int c,int k) { int p=++cnt,f=lst;lst=p; len[p]=len[f]+1; pos[p].push_back(k);rt[p]=change(rt[p],1,n-1,k); while(f&&!son[f][c]) son[f][c]=p,f=fa[f]; if(!f) {fa[p]=1;return;} int x=son[f][c]; if(len[f]+1==len[x]) {fa[p]=x;return;} int y=++cnt;len[y]=len[f]+1; fa[y]=fa[x],fa[x]=fa[p]=y;son[y]=son[x]; while(f&&son[f][c]==x) son[f][c]=y,f=fa[f];}int merge(int a,int b,int x,int y) { if(!a||!b) return a+b; if(x==y) {t[a]+=t[b];d[a]+=d[b];} int mid=x+y>>1; l[a]=merge(l[a],l[b],x,mid);r[a]=merge(r[a],r[b],mid+1,y); t[a]=t[l[a]]+t[r[a]],d[a]=d[l[a]]+d[r[a]]; return a;}int main() { n=read(); for(re int i=1;i<=n;++i) a[i]=read(); for(re int i=1;i
=0;--i) A[tax[len[i]]--]=i; for(re int i=cnt;i;--i) { int x=A[i],F=fa[x]; if(pos[x].size()>pos[F].size()) std::swap(pos[x],pos[F]),std::swap(rt[x],rt[F]); for(re int j=0;j

转载于:https://www.cnblogs.com/asuldb/p/10557181.html

你可能感兴趣的文章
交换机/路由器上的 S口 F口 E口
查看>>
P1298(矩阵切割)DP
查看>>
wzplayer for delphi demo截图
查看>>
团队第二周:SRS文档
查看>>
Zookeeper的安装与使用:
查看>>
密码策略限制最大与最小长度
查看>>
正则表达式模式
查看>>
使用iframe实现同域跨站提交数据
查看>>
Mouse点击之后,复制GridView控件的数据行
查看>>
ASP.NET开发,从二层至三层,至面向对象 (2)
查看>>
如何查看自己电脑支持OpenGL core版本
查看>>
Halcon使用的3D相机模型-camera_calibration
查看>>
页面元素定位 XPath 简介
查看>>
[转]loadrunner:系统的平均并发用户数和并发数峰值如何估算
查看>>
Linux下Tomcat重新启动
查看>>
HTML Table to Json
查看>>
Theano 学习笔记(一)
查看>>
1.7 节点进行排序显示
查看>>
web最佳实践
查看>>
spring 集成shiro 之 自定义过滤器
查看>>