2018 ICPC南京 M.Mediocre String Problem 回文树+拓展kmp

CH569 USBSS库函数分析 CH569 USB3.0 解析 阅读详情

题目链接:https://nanti.jisuanke.com/t/33682

这是一道高级板子题。。。要用到两个算法,exkmp和回文树,没学过的建议去学一下

题目要找出s[i..j]+t[0...k]是回文串的(i,j,k)元组个数。

先将s串倒置之后分两步求,假设最后的串中间分隔点为a

①满足s[i...a]和t[k...0]相同(因为是回文串,所以首尾倒过来一定相同)用exkmp找出对于每个s[i]的extend值,就是取的种类数

②接下来要满足s[a+1...t]是回文串,且其长度不能为0

这个直接用回文树套一下,计算出每个点对应多少个本质不同的回文串就好了记为cou【i】

最后的答案就是对每个extend【i】!=0 && i!=n-1(这个不等于n-1是因为要求j-i+1一定要大于k,所以中间部分的回文串长不能是0),贡献值加上extend【i】*cou【i+1】

#include<bits/stdc++.h>

using namespace std;


const int maxn=1e6+10;///多个模式串长度
const int N=26;///文章长度
const int lettersize=26;///看种类

const int MAXN=1e6+10;

char s[maxn];
char no[maxn];
long long sum[maxn],cou[maxn];

///next1[i]:x[0...m-1]与x[i...m-1]的最长公共前缀
///extend[i]:y[i...n-1]与x[0...m-1]的最长公共前缀

int next1[maxn],extend[maxn];
char y[maxn],x[maxn];

void pre_exkmp()
{
    int n=strlen(y);
    int m=strlen(x);
    next1[0]=m;
    int j=0;
    while(j+1<m && x[j]==x[j+1])j++;
    next1[1]=j;
    int k=1;
    for(int i=2;i<m;i++)
    {
        int p=next1[k]+k-1;
        int L=next1[i-k];
        if(i+L<p+1)next1[i]=L;
        else
        {
            j=max(0,p-i+1);
            while(i+j<m && x[i+j]==x[j])j++;
            next1[i]=j;
            k=i;
        }
    }
}


void exkmp()
{
    int n=strlen(y);
    int m=strlen(x);
    pre_exkmp();
    int j=0;
    while(j<n && j<m && x[j]==y[j])j++;
    extend[0]=j;
    int k=0;
    for(int i=1;i<n;i++)
    {
        int p=extend[k]+k-1;
        int L=next1[i-k];
        if(i+L<p+1)extend[i]=L;
        else
        {
            int p=extend[k]+k-1;
            int L=next1[i-k];
            if(i+L<p+1)extend[i]=L;
            else
            {
                j=max(0,p-i+1);
                while(i+j<n && j<m && y[i+j]==x[j])j++;
                extend[i]=j;
                k=i;
            }
        }
    }
}



int _next1[MAXN][N] ;//_next指针,_next指针和字典树类似,指向的串为当前串两端加上同一个字符构成
int fail[MAXN] ;//fail指针,失配后跳转到fail指针指向的节点
int cnt[MAXN] ;//节点i表示的本质不同的串的个数
int num[MAXN] ;//以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数
int len[MAXN] ;//len[i]表示节点i表示的回文串的长度
int S[MAXN] ;//存放添加的字符
int last ;//指向上一个字符所在的节点,方便下一次add
int n ;//字符数组指针
int p ;//节点指针

int newnode ( int l ) {//新建节点
    for ( int i = 0 ; i < N ; ++ i ) _next1[p][i] = 0 ;
    cnt[p] = 0 ;
    num[p] = 0 ;
    len[p] = l ;
    return p ++ ;
}

void init () {//初始化
    p = 0 ;
    newnode (  0 ) ;
    newnode ( -1 ) ;
    last = 0 ;
    n = 0 ;
    S[n] = -1 ;//开头放一个字符集中没有的字符,减少特判
    fail[0] = 1 ;
}

int get_fail ( int x ) {//和KMP一样,失配后找一个尽量最长的
    while ( S[n - len[x] - 1] != S[n] ) x = fail[x] ;
    return x ;
}

int add ( int c ) {
    c -= 'a' ;
    S[++ n] = c ;
    int cur = get_fail ( last ) ;//通过上一个回文串找这个回文串的匹配位置
    if ( !_next1[cur][c] ) {//如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串
        int now = newnode ( len[cur] + 2 ) ;//新建节点
        fail[now] = _next1[get_fail ( fail[cur] )][c] ;//和AC自动机一样建立fail指针,以便失配后跳转
        _next1[cur][c] = now ;
        num[now] = num[fail[now]] + 1 ;
    }
    last = _next1[cur][c] ;
    cnt[last] ++ ;
    return last;
}

void count () {
    for ( int i = p - 1 ; i >= 0 ; -- i ) cnt[fail[i]] += cnt[i] ;
    //父亲累加儿子的cnt,因为如果fail[v]=u,则u一定是v的子回文串!
}







int main()
{
    while(~scanf("%s%s",no,s))
    {
        memset(sum,0,sizeof(sum));
        memset(cou,0,sizeof(cou));
        int n=strlen(no),m=strlen(s);
        for(int i=0;i<n;i++)
            y[i]=no[n-1-i];
            y[n]='\0';
        for(int i=0;i<m;i++)
            x[i]=s[i];
        exkmp();
        for(int i=0;i<n/2;i++)
        {
            int tem=extend[i];
            extend[i]=extend[n-i-1];
            extend[n-i-1]=tem;
        }

        ///回文树
        init();

        for(int i=n-1;i>=0;i--)
        {
            cou[i]=add(no[i]);
        }
        count();
        for(int i=0;i<n;i++)
            cou[i]=num[cou[i]];
        long long ans=0;
        for(int i=0;i<n;i++)
            {
                if(extend[i])
                {
                    if(i==n)
                        continue;
                    else
                        ans+=1LL*extend[i]*cou[i+1];
                }
            }
            printf("%lld\n",ans);

    }
    return 0;
}

 

电子元器件选型与实战应用—01 电阻选型 大家好, 我是记得诚。这是《电子元器件选型与实战应用》专栏的第一篇文章,今天的主角是电阻,在每一个电子产品中,都少不了电阻的身影,其重要性不言而喻。 阅读详情

相关推荐

计算机毕业设计springboot基于微信平台的二次元手办商场小程序【附源码】

选题背景: 随着二次元文化的兴起和普及,越来越多的人开始对二次元角色产生了浓厚的兴趣和喜爱。手办作为二次元文化的重要载体之一,成为了许多二次元爱好者收藏和展示的对象。然而,在传统的线下手办商场中,消费者往往面临着时间、空间和选择的限制。因此,基于微信平台的二次元手办商场小程序应运而生。 选题意义: 首先,基于微信平台的二次元手办商场小程序能够打破地域限制,使得用户可以随时随地通过手机进行购物。无论是在家中、上班途中还是旅行中,用户都能够方便地浏览和购买自己喜欢的手办,极大地提高了购物的便利性和灵活性。

拉期程序 452

Mediocre String Problem Gym - 101981M

https://cn.vjudge.net/problem/Gym-101981M 很容易tle #include <iostream> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <cstdio&gt...

newhonor 291

Windows11上CUDA 12.3配PyTorch踩坑记:一条官网命令救了我的GPU加速

本文详细介绍了在Windows 11上配置CUDA 12.3与PyTorch的完整指南,包括环境准备、安装要点、兼容性解决方案和性能验证。通过官方推荐的conda命令和实用技巧,帮助开发者解决常见问题,实现高效的GPU加速,提升深度学习开发效率。

weixin_42528974的博客 109

Mediocre String Problem(马拉车+扩展KMP)

文章目录[Mediocre String Problem](https://codeforces.com/gym/101981)题目大意解题思路代码 Mediocre String Problem 题目大意 给你一个串S,和一个串T,从S中选一个子串做前缀串然后与T的一个前缀串做后缀串组成新的字符串是一个回文串,而且S的子串的长度需要比T的前缀串的长度要长。问你有多少种选取方法。 解题思路 假设我们选取S串的S[i:j]S[i:j]S[i:j]和T串的T[1:K]T[1:K]T[1:K]组成的新串是一个回文

qq_43750980的博客 480

threejs加载3dtiles(倾斜摄影)数据

1、安装3dTilesRenderer 插件 使用npm 安装 npm install 3d-tiles-renderer --save 或者去官网下载都行 GitHub - NASA-AMMOS/3DTilesRendererJS: Renderer for 3D Tiles in Javascript using three.js 2、使用 首先引入,在填入3dtiles数据的地址,可以是文件路径也可以是网站路径 const tilesRenderer = new TilesRend..

weixin_39481659的博客 1万+

ClearML中文文档实战:从安装到第一个实验的保姆级教程

本文提供ClearML从零开始的实战指南,涵盖核心组件理解、Python SDK安装、服务器配置及首个自动化实验的完整流程。通过改造PyTorch训练脚本的实例,详细演示了如何利用ClearML自动记录实验参数、指标与模型,实现机器学习实验的可复现性与高效管理,并简要介绍了进阶的自动化工作流。

weixin_29216049的博客 398

Mediocre String Problem(exkmp+manacher+差分

#include<bits/stdc++.h> using namespace std; const int N=2e6+10; int Ma[N],Mp[N]; int cnt[N],to[N],cnt2[N]; void Manacher(char s[],int len){ int l=0; Ma[l++]='$'; Ma[l++]='#'; for(int i=0;i<len;i++){ to[l]=i; Ma[l++

我们仍未知道那天所看见的花的名字。 234

opencv 常用函数总结

本文是一份OpenCV图像处理的常用函数总结,详细介绍了图像的读入、显示、保存、像素处理、图像属性获取、基础操作、阈值处理、图像平滑、形态学转换以及直方图处理等关键技术。文章通过代码示例和参数说明,帮助读者快速掌握OpenCV在图像处理领域的应用。

weixin_44063529的博客 1599

[ICPC2018南京站M] 回文树+exKMP

题意: 思路: 我们可以通过将s串倒转过来与t串跑一遍exKMP,然后再遍历一遍extend数组,在遍历的过程中将倒过来的s串加入到回文树中,当前位置i上的答案实际上就是extend[i]乘上以i开始的回文串个数,由于我们是倒过来添加的,所以实际上是以i结尾的回文串个数,这个只需要稍加修改即可实现。 import java.io.OutputStream; import java.io...

Garett的博客 288

【Halcon-2D测量】add_metrology_object_rectangle2_measure 函数功能(用于向2D计量模型中添加旋转矩形(rectangle2类型)计量对象)

HALCON算子add_metrology_object_rectangle2_measure解析摘要 该算子是HALCON 2D计量模块的核心算子,用于添加旋转矩形计量对象并配置测量参数。主要功能包括:定义旋转矩形几何轮廓(中心坐标、主轴角度、长短半长);生成垂直于矩形边界的测量区域;设置边缘提取预处理参数(高斯平滑、振幅阈值)。关键注意事项:MeasureLength1必须小于矩形长短半长;角度参数Phi需使用弧度单位;多线程需同步模型句柄。该算子适用于方形螺母、PCB板边框等矩形零件的精密测量,需与a

weixin_45590420的博客 1223

AI智能体实战:从LangChain到多智能体协作的自动化新范式

在人工智能技术快速发展的今天,大语言模型(LLM)已成为推动自动化变革的核心驱动力。其原理在于通过深度学习海量文本数据,使模型能够理解、生成自然语言并执行推理任务。这一技术进步催生了AI智能体(AI Agent)这一新兴概念,它赋予自动化系统自主决策和动态规划能力,从而突破了传统脚本和RPA工具在固定流程上的局限。从技术价值看,AI智能体框架通过封装LLM调用、工具集成与流程编排,显著降低了构建复杂人机协同应用的开发门槛。在实际应用场景中,智能体尤其擅长处理信息调研、内容创作辅助、数据分析等需要处理非结构化

weixin_33730836的博客 773

回文树介绍(Palindromic Tree)

简介回文树是由Mikhail Rubinchik大神发明的,在Petrozavodsk Summer Camp 2014上首次提出来,是一个很新的数据结构,目前相关资料比较少。顾名思义,回文树是一个用来解决回文串相关问题。回文树的结构就像线段树、平衡树等其它树结构一样,回文树由若干个节点组成,每个节点代表一个回文串(palindrome)。节点 例子:四个节点的回文串边节点之间通过有向边连接起来,

BananaTree 1万+

OpenStack ussuri 私有云平台搭建企业级实战

openstack是一个云操作系统,这个操作系统控制着数据中心中的计算,存储和网络资源。所有这些资源的管理都是通过API来来实现的,并且管理资源都有相应的认证机制。在openstack中有一个叫做dashboard的仪表盘,这个仪表盘通过web界面可以管理这些在DC中的资源。除了能提供IaaS功能外,你还可以使用orchestration,错误管理和服务管理等服务来确保应用的高可用性。

悦分享 2338

2018 ACM-ICPC 南京站 M.Mediocre String Problem 回文树+二分hash/拓展kmp

Given two stringsssandtt, count the number of tuples(i, j, k)(i,j,k)such that 1 \le i \le j \le |s|1≤i≤j≤∣s∣ 1 \le k \le |t|1≤k≤∣t∣. j - i + 1 > kj−i+1>k. Theii-th character ofssto t...

pxlsdz的博客 399

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

2018 ACM-ICPC 南京站 OnSite M Mediocre String Problem

2018 ACM-ICPC 南京站 OnSite M Mediocre String Problem M. Mediocre String Problem 题目链接 题面: 划掉 题意: 见题面 思路: 马拉车+EKmp 由题意可以知道,当串s和串t匹配的时候,有下面这个情况 因此,可以用马拉车处理出s串以每个位置作为起点的回文串的个数。 用RL数组+BIT区间更新单点查询即可。 之后将s串翻...

LFhase‘s Blog 567

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

2018 ICPC 南京 M. Mediocre String Problem (马拉车+扩展kmp)

题链:https://nanti.jisuanke.com/t/A2150 题意:给出两个串S,T。求S的子串接上T的前缀子串(S子串的长度要大于T前缀子串的长度。)所能组成的回文串的个数。 思路:我们可以把S的子串s分为两部分s1和s2。那么s2一定得是回文串且长度要大于1,s1与T的子串t又组成回文串。 马拉车求出S(假设为cbaba)的每个回文子串。 对于回文子串“aba”,可选的s2有 1.“b”(对应的s1可以为"a","ba","cba",那么我们需要的T的子串前缀为"a","ab",

birdmanqin的博客 347

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ACM-ICPC2018南京赛区 Mediocre String Problem

Mediocre String Problem 题解: 很容易想到将第一个串反过来,然后对于s串的每个位置可以求出t的前缀和它匹配了多少个(EXKMP 或者 二分+hash)。 然后剩下的就是要处理以某个位置为结束的回文串有多少个(manacher + 差分),因为要求s串选取的要多一点。这道题是个痛啊。。。当时的金牌题,不会EXKMP可以用二分+字符串hash啊,比赛前的暑假还写过,比赛时...

weixin_34080903的博客 209

2018南京icpc M.Mediocre String Problem(exKMP or SAM)

题目:给串s和串t,求从s中取一个子串,再和t的一个前缀拼接起来能组成回文串的个数,要求从s取的子串比取的t的前缀长。 可以用扩展kmp+回文算法做,也可以用sam替代扩展kmp,但是很难写。 回文算法用马拉车和回文树都可以,但是这里要求的是“从当前位置开始有多少回文串”,马拉车的数组要经过处理才能用,回文树就可以直接用了… 果然回文树各种方面都完爆马拉车,只是有点长。 可以用扩展kmp求出s串的...

Cymbals的博客 779

18南京 Gym - 101981M Mediocre String Problem 扩展kmp+马拉车

题目链接:https://vjudge.net/problem/Gym-101981M 题意:求 s的一个子串后面加上t的前缀为回文串并且满足|s| > |t| 的个数 题解:因为牵扯到了前缀和子串的问题,大体就能想到要用到扩展kmp,我们把s倒置,那么问题就转化为了,对于s串的每一个位置pos的后缀和t前缀的公共长度* 以pos-1为结尾的回文串个数 的总和,求公共长度就是扩展kmp...

还我笑颜 396

2018ICPC南京 Problem M. Mediocre String Problem(回文串,马拉车,扩展KMP)

题意: 给你两个字符串s,ts,ts,t,要求从sss中找到一个子串和ttt的一个前缀拼起来,结果要是回文串。求多少种拼法。 思路: 借此题复习了一下字符串算法。 首先sss中找到的子串可以分为两部分:s1+s2s1+s2s1+s2,s1s1s1一定是ttt一个前缀的逆反串,s2s2s2一定是个回文串。 所以可以将一开始所给的sss串反一下,然后算出每个右端点iii对应回文串的个数,再找到[i+1,len][i+1,len][i+1,len]部分与ttt串的最长公共前缀,二者相乘就是答案。 算回文串的过程.

tomjobs的博客 524

ICPC 2018 南京 Mediocre String Problem

题解: 题目的意思就是在第一个串里找“s1s2s3”,第二个串里找“s4”,如上拼接后,是一个回文串,求方案数 可以发现,s1与s4是回文的,s2和s3是回文的,我们枚举s1的右端点,s1的长度乘以s2起始点为左边界的回文串的数量,累加就是答案。 现在分两部分,一是求s1,二是求以每个点为左边界的回文串的数量 一的话,就是求每个后缀匹配第二个串的LCP,可以用扩展kmp求得,也可以...

Spy97的博客 1217

ACM-ICPC 2018 南京赛区网络预赛 I.Skr(Manacher马拉车+Hash哈希/回文树)

题目 给一个只由数字构成的字符串s(|s|<=2e6) 求s的所有本质不同字符串之和%1e9+7, 每一个不同字符串的贡献为其十进制下的值 思路来源 https://blog.csdn.net/sodacoco/article/details/83240305(Hash相关) https://blog.csdn.net/dllpXFire/article/details/8231...

小衣同学的博客 493

M - Mediocre String Problem( 扩展KMP + Manacher + 差分 )

M - Mediocre String Problem( 扩展KMP + Manacher + 差分 ) 题意:给出一个串S,和一个串T. 要求 从S串中取一个子串,后面接上T串的一个前缀 组成一个结果串,(要求S串的部分比T串的部分长),结果串是回文串的个数。 思路: S串贡献的部分 可以分成两部分,S1+S2; 前面的S1 是T部分的反转; S2 就只能是回文串,因为S串的部分必须比T的多,所以S2长度必须大于等于1 然后我们可以分成两部分,首先先把S中的所有回文串求出,可以用(回文.

石旭先森的博客 841

ICPC2020 南京 M Monster Hunter

题意: 牛客ICPC2020南京的M题 这道题考场上写了两个小时,奈何最近dp练习太少,写了半天把自己绕晕了,现在来重新捋一下思路。 首先很明确的一点,使用的药水要从小往大进行dp(尝试过从大到小,没办法列方程)。先观察一下要些什么状态:当前节点,以他为根的子树用了多少瓶药,他自己是否用药被杀。最后一个状态我在考场上设立的是是否被杀,其实本质上是一样的。 下面来解释dp的含义:dp[i][j][0/1]dp[i][j][0/1]dp[i][j][0/1]以iii为根的子树中,用jjj瓶药,iii是否被用药杀

萍水相逢,尽是他乡之客 621

2018 ICPC 南京 M题 Mediocre String Problem ——Gym - 101981M

http://fastvj.rainng.com/problem/Gym-101981M http://codeforces.com/gym/101981/attachments 题意:给你两个串s和t串,从s串中选出一个子串,然后再t串中取一个前缀出来,组合出是回文串一共有多少中方法。 做法:这道题,我训练的时候想到了用找出t串在s串中匹配的位置,然后找出s串中每一个起点开始的回文串的数量...

KXL5180的博客 542

2018 ICPC 南京 M. Mediocre String Problem(ExKMP + Manacher / ExKMP+回文树)

2018 ICPC 南京 全文见:https://blog.csdn.net/qq_43461168/article/details/112796538 M. Mediocre String Problem 题意:给定两个串s和t。三元组(i,j,k)表示 s[i-j] + t[0-k],有多少个三元组使得结果串是回文串。简单来说就是在s中找一个子串 ,与t的前缀连起来变成回文串。求方案数。 !思路参考:https://www.cnblogs.com/luowentao/p/10332309.html 思路

qq_43461168的博客 519
上一篇: Greater New York Region 2015 G compositions dp
下一篇: 比赛总结 mid | ans
Dale_zero
博客等级 码龄9年 10粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值