这个是满分做法, 68pts 做法在上一篇博客中 
会 68 pts 做法后就十分简单了,只要来一遍线段树合并 right 集合并在匹配的时候判一下是否在 $[l,r]$ 区间中即可
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 5000000
#define N 30
#define ll long long
#define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)
using namespace std; char str[maxn],ss[maxn];
int str_len,ss_len;
int nodes;
int C[maxn],rk[maxn];
int rt[maxn];
int pos[maxn],mx[maxn]; struct Segment_Tree{ int l,r,sumv; }node[maxn<<2];
int newnode(){ return ++nodes; }
void modify(int p,int l,int r,int &o){
if(!o) o=newnode();
++node[o].sumv;
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) modify(p,l,mid,node[o].l);
else modify(p,mid+1,r,node[o].r);
}
int merge(int x,int y){
if(!x||!y) return x+y;
int o=newnode();
node[o].sumv=node[x].sumv+node[y].sumv;
node[o].l=merge(node[x].l,node[y].l);
node[o].r=merge(node[x].r,node[y].r);
return o;
}
int query(int l,int r,int L,int R,int o){
if(l>r||r<L||l>R) return 0;
if(l>=L&&r<=R) return node[o].sumv;
int mid=(l+r)>>1,res=0;
if(node[o].l) res+=query(l,mid,L,R,node[o].l);
if(node[o].r) res+=query(mid+1,r,L,R,node[o].r);
return res;
} struct SAM{
int last,tot,dis[maxn],ch[maxn][N],f[maxn],pos[maxn];
void init() { last=++tot; }
void ins(int c,int y,int z,int rot){
int p=last,np=++tot; last=np; dis[np]=dis[p]+1; pos[np] = z;
while(p&&!ch[p][c])ch[p][c]=np,p=f[p];
if(!p) f[np]=rot;
else{
int q=ch[p][c],nq;
if(dis[q]==dis[p]+1) f[np]=q;
else{
nq=++tot;
dis[nq]=dis[p]+1;
pos[nq] = pos[q];
memcpy(ch[nq],ch[q],sizeof(ch[q]));
f[nq]=f[q],f[q]=f[np]=nq;
while(p&&ch[p][c]==q) ch[p][c]=nq,p=f[p];
}
}
if(y) modify(y,1,str_len,rt[np]);
}
void build_S1(){
for(int i=1;i<=tot;++i) C[dis[i]]++;
for(int i=1;i<=tot;++i) C[i]+=C[i-1];
for(int i=1;i<=tot;++i) rk[C[dis[i]]--]=i;
for(int i=tot;i>=1;--i) {
int p=rk[i];
rt[f[p]] = merge(rt[f[p]],rt[p]);
}
}
}S1,S2; int main(){
//setIO("input");
scanf("%s",str+1),str_len=strlen(str+1),S1.init();
for(int i=1;i<=str_len;++i) S1.ins(str[i]-'a',i,0,1);
S1.build_S1();
int queries,l,r,st,ed;
scanf("%d",&queries);
while(queries--) { S2.init(),st=S2.tot,scanf("%s%d%d",ss+1,&l,&r),ss_len=strlen(ss+1); for(int i=1;i<=ss_len;++i) S2.ins(ss[i]-'a',0,i,st); ed=S2.tot; int cnt=0,p=1;
long long ans = 0; for(int i=1;i<=ss_len;++i) {
int c=ss[i]-'a';
while(1){
if(S1.ch[p][c] && query(1,str_len,l+cnt,r,rt[S1.ch[p][c]]))
{
++cnt,p=S1.ch[p][c]; break;
}
else {
if(!cnt) {p=1;break; }
--cnt;
if(cnt==S1.dis[S1.f[p]]) p=S1.f[p];
}
}
mx[i]=cnt;
} for(int i=st;i<=ed;++i)
ans+=max(0,S2.dis[i]-max(mx[S2.pos[i]],S2.dis[S2.f[i]]));
printf("%lld\n",ans);
}
return 0;
}

  

最新文章

  1. 1元搭建自己的云服务器&amp;解析域名
  2. SQL查询某个时间段共多少条数据
  3. Text文档编码识别方法
  4. jQuery瀑布流简单示例
  5. C# 获取 oracle 存储过程的 返回值1
  6. dede数据库类使用方法 $dsql
  7. vim编辑器的基本使用
  8. Tomcat 在win7/win8 系统下tomcat-users.xml.new(拒绝访问)解决方法
  9. 流媒体学习四------- ortp队列的实现
  10. Android开发者应该深入学习的10个开源应用项目
  11. .htaccess的基本作用及相关语法介绍
  12. (转载)struts2的驱动模型
  13. Effective C++学习笔记 条款07:为多态基类声明virtual析构函数
  14. XtraGrid的若干种用法 z
  15. table表格中加入&lt;a&gt;标签,使内容上下居中的方法。
  16. winPcap_4_获取已安装设备的高级信息
  17. css实现背景渐变色效果
  18. java基础(十五章)
  19. pdf中内嵌字体问题
  20. gulp 编译es6 react 教程 案例 配置

热门文章

  1. vue-router 设置默认路由
  2. Lost Cows POJ - 2182 二分 + 树状数组
  3. Django Views Decorator
  4. kvm三个kernel相关的调优
  5. 一篇文章彻底弄懂Base64编码原理(转载)
  6. IOS - JSON数据解析 小3种方法
  7. js常用事件及事件对象
  8. 2015 Multi-University Training Contest 8 hdu 5390 tree
  9. java整型byte,short,int,long取值范围大小
  10. call to OpenGL ES API with no current context 和Fatal signal 11