HDU 3948 不同回文子串个数

集训队论文中有求不同子串个数的做法,就是扫一遍height数组,过程中根据height数组进行去重。对于本题也是雷同的,只是每一次不是根据与排名在上一位的LCP去重,而是与上一次统计对答案有贡献的后缀进行比较去重。

几组数据

abacaba 7

abbacaa 7

baabcaa 5

  1 #include <iostream>
  2 #include <vector>
  3 #include <algorithm>
  4 #include <string>
  5 #include <string.h>
  6 #include <stdio.h>
  7 #include <queue>
  8 #include <stack>
  9 #include <map>
 10 #include <set>
 11 #include <cmath>
 12 #include <ctime>
 13 #include <cassert>
 14 #include <sstream>
 15 using namespace std;
 16 
 17 const int N=123456*2;
 18 
 19 char s[N];
 20 struct SuffixArray {
 21      int wa[N], wb[N], cnt[N], wv[N];
 22     int rk[N], height[N];
 23     int sa[N];
 24     bool cmp(int r[], int a, int b, int l) {
 25         return r[a] == r[b] && r[a+l] == r[b+l];
 26     }
 27     void calcSA(char r[], int n, int m) {
 28         int i, j, p, *x = wa, *y = wb;
 29         for (i = 0; i < m; ++i) cnt[i] = 0;
 30         for (i = 0; i < n; ++i) cnt[x[i]=r[i]]++;
 31         for (i = 1; i < m; ++i) cnt[i] += cnt[i-1];
 32         for (i = n-1; i >= 0; --i) sa[--cnt[x[i]]] = i;
 33         for (j = 1, p = 1; p < n; j *= 2, m = p) {
 34             for (p = 0, i = n - j; i < n; ++i) y[p++] = i;
 35             for (i = 0; i < n; ++i) if (sa[i] >= j) y[p++] = sa[i] - j;
 36             for (i = 0; i < n; ++i) wv[i] = x[y[i]];
 37             for (i = 0; i < m; ++i) cnt[i] = 0;
 38             for (i = 0; i < n; ++i) cnt[wv[i]]++;
 39             for (i = 1; i < m; ++i) cnt[i] += cnt[i-1];
 40             for (i = n-1; i >= 0; --i) sa[--cnt[wv[i]]] = y[i];
 41             for (swap(x, y), p = 1, x[sa[0]] = 0, i = 1; i < n; ++i)
 42                 x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1 : p++;
 43         }
 44     }
 45     void calcHeight(char r[], int n) {
 46         int i, j, k = 0;
 47         for (i = 0; i <= n; ++i) rk[sa[i]] = i;
 48         for (i = 0; i < n; height[rk[i++]] = k)
 49             for (k?k--:0, j = sa[rk[i]-1]; r[i+k] == r[j+k]; k++);
 50     }
 51     int lcp(int a,int b,int len) {
 52         if (a==b) return len-a;
 53         int ra=rk[a],rb=rk[b];
 54         if (ra>rb) swap(ra,rb);
 55         return queryST(ra+1,rb);
 56     }
 57     int st[N][22];
 58     void initST(int n) {
 59         for (int i=1; i<=n; i++)
 60             st[i][0]=height[i];
 61         for (int j=1; (1<<j)<=n; j++) {
 62             int k=1<<(j-1);
 63             for (int i=1; i+k<=n; i++)
 64                 st[i][j]=min(st[i][j-1],st[i+k][j-1]);
 65         }
 66     }
 67     int queryST(int a,int b) {
 68         if (a>b) swap(a,b);
 69         int dis=b-a+1;
 70         int k=log((double)dis)/log(2.0);
 71         return min(st[a][k],st[b-(1<<k)+1][k]);
 72     }
 73     void solve(int cas) {
 74         int n=strlen(s);
 75         s[n]='#';
 76         for (int i=0;i<n;i++) {
 77             s[n+1+i]=s[n-1-i];
 78         }
 79         int o=n;
 80         n=2*n+1;
 81         s[n]='\0';
 82         calcSA(s,n+1,128);
 83         calcHeight(s,n);
 84         initST(n);
 85         long long ret=0;
 86         int curLcp=0;
 87         for (int i=1;i<=n;i++) { //odd
 88             int pos=sa[i];
 89             curLcp=min(curLcp,height[i]);
 90             if (pos<o) {
 91                 int ops=n-1-pos;
 92                 int now=lcp(pos,ops,n);
 93                 ret+=max(0,now-curLcp);
 94                 if (now>=curLcp)
 95                     curLcp=now;
 96             }
 97         }
 98         curLcp=0;
 99         for (int i=1;i<=n;i++) { //even
100             int pos=sa[i];
101             curLcp=min(curLcp,height[i]);
102             if (pos<o) {
103                 int ops=n-pos;
104                 int now=lcp(pos,ops,n);
105                 ret+=max(0,now-curLcp);
106                 if (now>=curLcp)
107                     curLcp=now;
108             }
109         }
110         printf("Case #%d: %I64d\n",cas,ret);
111     }
112 }suf;
113 
114 int main () {
115     //freopen("out.txt","r",stdin);
116     int T;
117     scanf("%d",&T);
118     int cas=1;
119     while (T--) {
120        scanf("%s",s);
121        suf.solve(cas);
122        cas++;
123     }
124     return 0;
125 }
View Code

 

转载于:https://www.cnblogs.com/micrari/p/4993359.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272705.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle 11g重新安装配置,Oracle 11g数据库安装和卸载教程

Oracle11g的安装教程同时解压缩两个zip文件&#xff0c;生成一个database文件夹&#xff0c;进入到database文件夹&#xff0c;点击setup去掉安全更新的选项&#xff0c;直接下一步选择创建和配置数据库&#xff0c;点击下一步选择服务器类&#xff0c;点击下一步选择单例数据库…

程序员职业路线图

今天分享一张程序员职业路线图&#xff1a;欢迎关注我的公众号&#xff08;同步更新文章&#xff09;&#xff1a;DoNet技术分享平台阅读原文

C#编程规范整理

小编整理了一些C#编程的一些规范&#xff0c;希望对大家有点用处&#xff01;1、命名方式Pascal命名法&#xff1a;每个单词首字母均大写。Camel命名法&#xff1a;第一个单词首字母小写&#xff0c;其余单词首字母大写。2、有关类的规范1、使用 Pascal 大小写。2、用名词或名词…

win7 php redis 扩展,Windows中安装Redis及php redis扩展

Windows10环境安装Redis:1、下载Redis安装包&#xff1b;2、解压到自定义目录&#xff1b;3、windows键R&#xff0c;输入cmd 进入命令行&#xff0c;进入Redis的解压目录&#xff1b;4、运行&#xff1a;redis-server.exe redis.windows.conf 显示如下&#xff0c;说明启动成功…

【原创】MVC+ZTree实现权限树的功能

2、html代码权限树&#xff1a;3、JS代码var setting {async: {enable: true,url: /RoleToPerssion/GetPerssionTree,//异步加载时的请求地址autoParam: ["roleid"],//提交参数type: get,dataType: json},check: {enable: true, //true / false 分别表示 显示 / 不…

集合习题之列出有限集合所有子集

1、题目&#xff08;《离散数学及其应用》第6版P75 20 题&#xff09; 给出可以列出有限集合所有子集的步骤。 2、 解题思路 假设有集合A {a1, a2 … an}&#xff0c;列出其所有子集。 先列出含有1个元素的所有子集&#xff1a;{a1},{a2} … {an}然后列出含有2个元素的所有子…

C# partial 关键字的使用

C# 2.0 引入了局部类型的概念。局部类型允许我们将一个类、结构或接口分成几个部分&#xff0c;分别实现在几个不同的.cs文件中。局部类型适用于以下情况&#xff1a;(1) 类型特别大&#xff0c;不宜放在一个文件中实现。(2) 一个类型中的一部分代码为自动化工具生成的代码&…

线段的平移和旋转

//github不会用&#xff0c;试了很久不知道怎么上传代码 #include <iostream> using namespace std;#include <stdlib.h> #include <Eigen/Dense> #include <math.h> using namespace std; using Eigen::MatrixXd; int main() { int option; struct p…

我不问+你不说

阅读原文很多事我不问你不说这就是距离我问了你不说这就是隔阂我问了你说了这就是尊重你想说我想问这就是默契我不问你说了这就是信任很多事情你看到的听到的未必是你想象的那样人生在世多给别人机会解释多些向别人解释的耐心人生会少很多遗憾不问、不说、不解释这不是酷或有个…

怎么安装redhat linux操作系统,红帽RedHat Linux5系统安装指南

介绍如何安装linux操作系统&#xff0c;以目前市场主流的操作系统为例子进行介绍。1、放入安装dvd光盘&#xff0c;然后启动服务器&#xff0c;可得如下画面&#xff1a;2、按enter键&#xff0c;进入如下画面3、选择skip&#xff0c;按enter进入&#xff0c;下面画面&#xff…

研华工控机u盘启动安装linux系统,研华工控机怎么设置u盘启动

本文主要介绍研华IPC如何设置u盘启动研华IPC-610 IPC随XP版一起安装。有时安装控制软件需要在不满意时卸载。卸载未完成&#xff0c;这使得安装无法进行&#xff0c;因此您需要将系统恢复到相对纯粹的时间。通常&#xff0c;USB磁盘启动盘的安装系统首先备份初始纯XP作为备份&a…

UVA - 11732 strcmp() Anyone?左兄弟右儿子trie

input n 2<n<4000 s1 s2 ... sn 1<len(si)<1000 output 输出用strcmp()两两比较si,sj(i!j)要比较的次数&#xff0c;结果在long long范围内&#xff08;相同字符比较两次&#xff0c;不相同字符比较一次&#xff0c;包括\0&#xff09; 做法&#xff1a;由于字符集…

优秀程序员的十个习惯

在这个世界上&#xff0c;有数百万的人热衷于软件开发&#xff0c;他们有很多名字&#xff0c;如&#xff1a;软件工程师&#xff08;Software Engineer&#xff09;&#xff0c;程序员&#xff08;Programmer&#xff09;&#xff0c;编码人&#xff08;Coder&#xff09;&…

如何通俗地解释 C、C++、C#、Java、JavaScript、HTML、Python的用处

世界上本来没有计算机&#xff0c;工程师创造了它。为了让告诉计算机需要做什么事情&#xff0c;工程师发明了程序设计语言。简单粗暴的编程&#xff1a;C语言&#xff1a;用来学编程&#xff1b;C语言&#xff1a;用来使劲儿学编程&#xff1b;C#&#xff1a;用来在windows操作…

将c程序移植到linux,各位大侠:我把原来在linux运行的c程序移植到HPUNIX上出现了错误...

各位大侠&#xff1a;我把原来在linux运行的c程序移植到HPUNIX上出现了错误(2012-04-11 00:43:47)标签&#xff1a;linuxc程序杂谈各位大侠&#xff1a;我把原来在linux运行的c程序移植到HP_UNIX上出现了错误makefileCC aCC -AA W829 DD64 DAportable-I/ods/app/oracle/produc…

数据库学习建议之提高数据库速度的十条建议

很多网站的重要信息都是保存在数据库中的&#xff0c;用户通过提交访问数据库来获取用户信息。如果数据库速度非常的快&#xff0c;有助于节省服务器的资源&#xff0c;在这篇文章中&#xff0c;我收集了十个优化数据库速度的技巧。0. 小心设计数据库第一个技巧也许看来理所当然…

提高程序员工作效率的11个技巧

“吃苦耐劳”真的是优良品质吗&#xff0c;与你怎么做相比&#xff0c;老板们应该更关心你做了什么、达到的效果。所以&#xff0c;效率&#xff0c;还是效率&#xff0c;希望这些实用小技巧对大家有所帮助。1、两分钟法则如果一件事可以在两分钟内完成&#xff0c;比如回复邮件…

URI和URL及URN的区别

对于URL,大家都比较熟悉&#xff0c;其他两个词就比较陌生了。URI、URL和URN是识别、定位和命名互联网上的资源的标准途径。1989年Tim Berners-Lee发明了互联网&#xff08;World Wide Web&#xff09;。WWW被认为是全球互连的实际的和抽象的资源的集合–它按需求提供信息实体–…

Linux基础-目录与路径

今天我们一起来认识下linux中的目录与路径及操作其的一些常用命令。 说起路径就有绝对与相对之分&#xff0c;虽然简单&#xff0c;我们还是再啰嗦一下&#xff1a; 绝对路径&#xff0c;从系统的根目录/开始的目录都是相对路径&#xff0c;比如/usr/bin、/usr/local 相对路径…

28家知名IT公司名称的由来

28家IT公司名称由来&#xff0c;你知道吗&#xff1f;EMC、VMware、IBM、Oracle、NetApp、Citrix、Cisco、Google、Amazon、Alibaba、UCloud、Tencent、Baidu等著名的存储、备份或云计算行业的IT公司&#xff0c;相信你我都是耳熟能详&#xff0c;但这些公司的名称是如何而来的…