【经典dp】hdu4622Reincarnation
呕 卡64M内存卡了好久
题目描述
题目大意
给出一个字符串 S,每次询问一个区间的本质不同的子串个数。$|S| \le 2000$.
题目分析
首先无脑$n^2$个set开起来:MLE
稍微想想这个东西是能够区间dp的:对于一个字符串$[l,r]$,它的存在首先给所有包含$[l,r]$的$f[i][j]$贡献$1$;考虑相同的字符串下一次出现的位置$[l',r']$,那么对所有包含$[l,r']$的$f[i][j]$贡献$-1$。最后再按照顺序累加一下即可。
第一次:std::map存一个哈希值上一次出现的位置,MLE
第二次:手写哈希表,$\mod 8000007$挂链,MLE
第三次:手写哈希表,$\mod 5000007$挂链,MLE
第四次:手写哈希表,$\mod 10007$挂链,TLE?
第五次:手写哈希表,$\mod 500007$挂链、查询时候顺带后续修改,MLE???
嗯?这啥玩意?
啧。后来意识到枚举不同长度的时候,哈希表里历史记录值都是没用的。所以每次枚举长度都应该重置哈希表。而且这样一来,哈希表模数和空间就可以开小了。
还听说这个经典问题有一个$O(n)$做法?
网上找了一下只有两个类似的是:
1.loj#6070. 「2017 山东一轮集训 Day4」基因 强制在线询问$s[l\cdots r]$中有多少本质不同的回文子串 $n\le 10^5,q\le 2\times10^5$
2.「湖南省队集训2018 Day2」有趣的字符串题 每个询问会询问一段区间的本质不同回文子串个数 $n\le 3\times 10^5,m\le 10^6$
不过这两个题都要用到回文子串的性质:“一个串的所有回文后缀可以被划分成不超过log个等差数列”。所以网上尚没有找到这个问题的$O(n)$解法?
#include<bits/stdc++.h>
typedef unsigned long long uint;
const int maxn = ;
const int maxp = ;
uint base = ; struct node
{
uint num;
int val;
node(uint a=, int b=):num(a),val(b) {}
}edges[maxp];
struct Hash_Table
{
#define MO 10007
int head[],nxt[maxp],edgeTot;
void init(){edgeTot=,memset(head, -, sizeof head);}
int query(uint x, int c)
{
for (int i=head[x%MO]; i!=-; i=nxt[i])
if (edges[i].num==x){
std::swap(c, edges[i].val);
return c;
}
edges[++edgeTot] = node(x, c), nxt[edgeTot] = head[x%MO], head[x%MO] = edgeTot;
return ;
}
#undef MO
}g;
int T,n,q,l,r;
char s[maxn];
int f[maxn][maxn];
uint pwr[maxn],hsh[maxn],val; uint hash(int l, int r)
{
return hsh[r]-hsh[l-]*pwr[r-l+];
}
int main()
{
// freopen("hdu4622.in","r",stdin);
// freopen("hdu4622.out","w",stdout);
pwr[] = ;
for (int i=; i<=; i++)
pwr[i] = pwr[i-]*base;
for (scanf("%d",&T); T; --T)
{
scanf("%s",s+);
n = strlen(s+);
for (int i=; i<=n; i++) hsh[i] = hsh[i-]*base+s[i]-'a'+;
for (int i=; i<=n; i++)
for (int j=i; j<=n; j++) f[i][j] = ;
for (int d=; d<=n; d++)
{
g.init();
for (int i=,pos; i+d-<=n; i++)
{
val = hash(i, i+d-), pos = g.query(val, i);
if (pos) --f[pos][i+d-];
++f[i][i+d-];
}
}
for (int i=n; i>=; i--)
for (int j=i; j<=n; j++)
f[i][j] += f[i+][j]+f[i][j-]-f[i+][j-];
for (scanf("%d",&q); q; --q)
scanf("%d%d",&l,&r), printf("%d\n",f[l][r]);
}
return ;
}
END
【经典dp】hdu4622Reincarnation的更多相关文章
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- poj1458 求最长公共子序列 经典DP
Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 45763 Accepted: 18 ...
- NYOJ - 矩形嵌套(经典dp)
矩形嵌套时间限制:3000 ms | 内存限制:65535 KB 描述 有n个矩形,每个矩形可以用a,b来描述,表示长和宽.矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b< ...
- 51nod 1412 AVL树的种类(经典dp)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1412 题意: 思路: 经典dp!!!可惜我想不到!! $dp[i][k] ...
- NYOJ 16 矩形嵌套(经典DP)
http://acm.nyist.net/JudgeOnline/problem.php?pid=16 矩形嵌套 时间限制:3000 ms | 内存限制:65535 KB 难度: ...
- poj 1050 To the Max 最大子矩阵和 经典dp
To the Max Description Given a two-dimensional array of positive and negative integers, a sub-rect ...
- CS Academy Distinct Neighbours(经典dp)
CS Academy Distinct Neighbours(经典dp) 题意: 求相邻无相同数字的合法的排列数 题解: 题解 先将相同的数字分为一类,假设共有n组 定义\(dp[i][j]\)表示前 ...
- 【经典dp 技巧】8.13序列
经典的拆绝对值 题目大意 给定$n$个具有顺序的序列,允许对每个序列循环移动.记第$i$个序列尾元素为$x$,$i+1$个序列首元素为$y$,定义其连接收益为$|x-y|*i$,求$n$个序列连接最大 ...
- POJ 1160:Post Office 邮局经典DP
Post Office Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 17168 Accepted: 9270 Desc ...
随机推荐
- 第二次Java实验报告
Java实验报告 班级 计科二班 学号 20188437 姓名 何磊 完成时间 2019/9/12 评分等级 实验二 Java简单类与对象 实验目的 掌握类的定义,熟悉属性.构造函数.方法的作用,掌握 ...
- [转帖]国内拉取google kubernetes镜像
国内拉取google kubernetes镜像 2019年04月19日 01:19:03 willblog 阅读数 4231 标签: kubernetes 更多 个人分类: kubernetes ...
- #######【Python】【基础知识】【标准库】目录及学习规划 ######
下述参考Python DOC https://docs.python.org/zh-cn/3/library/index.html 概述 可用性注释 内置函数 内置常量 由 site 模块添加的常量 ...
- Java实现循环队列
一.分析 队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素.允许插入的一端称为队尾,允许删除的一端称为队头. 循环队列是一种以顺序存储结构表示的队列,为了解决“假溢出”问题而 ...
- Lucky Sorting(CodeForces-109D)【思维】
题意:给出一组数,要求从小到大排序,并且排序的过程中,发生交换的两个数至少一个为幸运数(十进制位均为4或7),问能否在(2×n)次交换内完成排序,如果能,输出交换的方案(不要求步骤数最少). 思路:首 ...
- SOSdp
layout: post title: SOSdp author: "luowentaoaa" catalog: true tags: mathjax: true - codefo ...
- sysbench测试
什么是基准测试 数据库的基准测试是对数据库的性能指标进行定量的.可复现的.可对比的测试. 基准测试与压力测试 基准测试可以理解为针对系统的一种压力测试.但基准测试不关心业务逻辑,更加简单.直接.易于测 ...
- 运用加密技术保护Java源代码(转)
出处:运用加密技术保护Java源代码 为什么要加密? 对于传统的C或C++之类的语言来说,要在Web上保护源代码是很容易的,只要不发布它就可以.遗憾的是,Java程序的源代码很容易被别人偷看.只要有一 ...
- Centos7:Solr4.10安装,配置与使用(tomcat环境)
配置jdk环境,安装tomcat 解压solr bin:是脚本的启动目录 contrib:第三方包存放的目录 dist:编译打包后存放目录,即构建后的输出产物存放的目录 docs:solr文档的存放目 ...
- 转:git上传本地项目到github
转自:https://blog.csdn.net/Lucky_LXG/article/details/77849212 将本地项目上传到Github(两种简单.方便的方法) 一.第一种方法:首先你需要 ...