当前位置: 首页 > news >正文

[十二省联考]字符串问题

SAM上定位子串然后通过parent树优化建图就可以了

由于一个节点可能会有很多串所以拆出来一些点就行了

//Love and Freedom.
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#define ll long long
#define inf 20021225
#define N 1600010
using namespace std;
vector<int> st[N]; int na,nb; char ch[N];
int poi,lt,rt,id[N]; int f[N][20]; int sz;
int ma(char c){return c-'a';}
int a[N],b[N],lst[N],m;
struct node{int fa,len,ch[26]; bool isa;}t[N];
struct edge{int to,lt;}e[N]; int cnt,in[N];
void insert(int c)
{
    int p=lt,np=lt=++poi; t[np].len=t[p].len+1;
    for(;p&&!t[p].ch[c];p=t[p].fa)    t[p].ch[c]=np;
    if(!p){t[np].fa=rt; return;}
    int q=t[p].ch[c];
    if(t[q].len==t[p].len+1){t[np].fa=q; return;}
    int nq=++poi; t[nq].fa=t[q].fa; t[q].fa=t[np].fa=nq;
    memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch)); t[nq].len=t[p].len+1;
    for(;p&&t[p].ch[c]==q;p=t[p].fa)    t[p].ch[c]=nq;
}
void build()
{
    for(int i=1;i<=poi;i++)    f[i][0]=t[i].fa;
    for(int j=1;j<=19;j++)
        for(int i=1;i<=poi;i++)    f[i][j]=f[f[i][j-1]][j-1];
}
void add(int x,int y){e[++cnt].to=y; e[cnt].lt=in[x]; in[x]=cnt;}
void locate(int l,int r,int flag)
{
    int ln=r-l+1; int x=id[l];
    for(int i=19;~i;i--)
        if(f[x][i] && t[f[x][i]].len>=ln)    x=f[x][i];
    t[++sz].isa=flag; t[sz].len=ln; st[x].push_back(sz);
}
bool cmp(int x,int y)
{
    return t[x].len>t[y].len || (t[x].len==t[y].len && t[x].isa>t[y].isa);
}
ll dp[N]; bool vis[N];
ll work(int x)
{
    if(vis[x])    return -1;
    //printf("MMP\n");
    if(~dp[x])    return dp[x];
    vis[x]=1; dp[x]=0;
    for(int i=in[x];i;i=e[i].lt)
    {
        ll to=work(e[i].to);
        if(to==-1)    return -1;
        dp[x]=max(dp[x],to);
    }
    vis[x]=0; dp[x]+=t[x].len; return dp[x];
}
void solve()
{
    scanf("%s",ch+1); int n=strlen(ch+1); lt=rt=++poi;
    for(int i=n;i;i--)    insert(ma(ch[i])),id[i]=lt;
    build(); scanf("%d",&na); sz=poi; int l,r;
    for(int i=1;i<=na;i++)    scanf("%d%d",&l,&r),locate(l,r,1),a[i]=sz;
    scanf("%d",&nb);
    for(int i=1;i<=nb;i++)    scanf("%d%d",&l,&r),locate(l,r,0),b[i]=sz;
    for(int i=1;i<=poi;i++)    sort(st[i].begin(),st[i].end(),cmp);
    for(int i=1;i<=poi;i++)
    {
        int tmp=i;
        for(int j=(int)st[i].size()-1;~j;j--)
        {
            int cur=st[i][j]; add(tmp,cur);
            if(!t[cur].isa)    tmp=cur;
        }
        lst[i]=tmp;// printf("!%d\n",tmp); 
    }
    for(int i=2;i<=poi;i++)    add(lst[t[i].fa],i);
    for(int i=1;i<=sz;i++)    if(!t[i].isa)
        t[i].len=0;
    scanf("%d",&m);
    int x,y; ll ans=0;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),add(a[x],b[y]);
    for(int i=1;i<=sz;i++)
    {
        ll tmp=work(i); if(tmp==-1){ans=-1;break;}
        ans=max(ans,tmp);
    }
    printf("%lld\n",ans);// poi=sz;
}
void clear()
{
    for(int i=1;i<=sz;i++)    st[i].clear(),memset(t[i].ch,0,sizeof(t[i].ch)),t[i].isa=0,t[i].len=0,t[i].fa=0;
    memset(dp,-1,sizeof(dp)); memset(vis,0,sizeof(vis)); memset(in,0,sizeof(in));
    //memset(id,0,sizeof(id)); memset(f,0,sizeof(f)); memset(lst,0,sizeof(lst));
    poi=cnt=lt=rt=sz=na=nb=0;
}
int main()
{
    int T;// memset(dp,-1,sizeof(dp));
    scanf("%d",&T); while(T--)
    {
        clear(); solve();
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/hanyuweining/p/10801730.html

相关文章:

  • FFmpeg 硬件加速方案概览 (下)
  • Vuex.js状态管理共享数据 - day8
  • 量子计算可以给企业竞争带来的七种优势
  • IT兄弟连 JavaWeb教程 Servlet线程安全问题
  • laravel5.5 视图共享数据
  • 小猿圈网站页面底部固定的方法
  • mysqlclient操作MySQL关系型数据库
  • Loadrunner报Failed to connect to server 127.0.0.1
  • poj1284(欧拉函数+原根)
  • 应用中有使用到集群么?多大规模?
  • Azure RIS的工作原理以及其与AWS RIs的比较
  • 使用DB业务拆分解决写压力大问题
  • JS中的值比较操作:==,===,Object.is()
  • 解决*.props打开失败问题
  • selector在手机上或浏览器显示各种姿势(虚拟下拉菜单)
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • 【391天】每日项目总结系列128(2018.03.03)
  • 【译】理解JavaScript:new 关键字
  • 〔开发系列〕一次关于小程序开发的深度总结
  • Angular6错误 Service: No provider for Renderer2
  • ES6--对象的扩展
  • ESLint简单操作
  • golang 发送GET和POST示例
  • iOS小技巧之UIImagePickerController实现头像选择
  • jQuery(一)
  • leetcode讲解--894. All Possible Full Binary Trees
  • Less 日常用法
  • Python 反序列化安全问题(二)
  • tweak 支持第三方库
  • Vue实战(四)登录/注册页的实现
  • 闭包,sync使用细节
  • 猴子数据域名防封接口降低小说被封的风险
  • 排序(1):冒泡排序
  • 区块链将重新定义世界
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 详解NodeJs流之一
  • 一份游戏开发学习路线
  • 从如何停掉 Promise 链说起
  • 第二十章:异步和文件I/O.(二十三)
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​Linux·i2c驱动架构​
  • #AngularJS#$sce.trustAsResourceUrl
  • #微信小程序(布局、渲染层基础知识)
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (09)Hive——CTE 公共表达式
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (循环依赖问题)学习spring的第九天
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • .htaccess配置重写url引擎
  • .NET Framework 4.6.2改进了WPF和安全性
  • .net mvc 获取url中controller和action
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)