hdu 4622 Reincarnation trie树+树状数组/dp
题意:给你一个字符串和m个询问,问你l,r这个区间内出现过多少字串。
连接:http://acm.hdu.edu.cn/showproblem.php?pid=4622
网上也有用后缀数组搞得、
思路(虎哥):用字典树把每一个字符串对应成一个整数 相同的字符串对应到相同的整数上
把所用的串对应的整数放在一个数组里 比如书字符串s[l...r]对应的整数是 k
那么二维数组 [l][r] 就等于k
假设一个对应好的二维数组 左下角是原点
3 4 5 2
2 3 4 0
1 6 0 0
2 0 0 0
这样求解 从l到r的不同字符串的个数 其实就是求 从[l][r] 到右下角所在的矩阵所包含不同整数的个数(不包括0)
这里需要一定的去重处理 处理后是
-1 0 1 1
0 1 1 0
1 1 0 0
1 0 0 0
然后一边dp就可以求出所有答案(因为是求一个矩形矩阵,所以我用了一个二维树状数组做的,感觉好慢- -。)
注意常用的next[26]写法的字典树有可能超内存 要优化
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <queue>
#define loop(s,i,n) for(i = s;i < n;i++)
#define cl(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&-x
using namespace std; const int maxm = ;
const int maxn = ; int head[maxm]; struct node
{
int next,v;
}g[maxm]; int cnt;
int c[maxn][maxn];
int pos[maxm];
char s[maxn];
int len;
void add(int a,int b,int val)
{
int i,j;
for(i = a;i <= len;i += lowbit(i))
{
for(j = b;j <= len;j += lowbit(j))
c[i][j] += val;
}
} int sum(int a,int b)
{
int res = ;
int i,j;
for(i = a;i > ;i -= lowbit(i))
{
for(j = b;j > ;j -= lowbit(j))
res+=c[i][j];
}
return res;
}
void insert(int &u,int key)
{
int i;
for(i = head[u];i != -;i = g[i].next)
{
int v;
v = g[i].v;
if(v == key)
{
u = i;
return ;
}
}
cnt++;
g[cnt].next = head[u];
g[cnt].v = key;
head[u] = cnt;
u = cnt;
return ;
}
int main()
{
int t;
//freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
len = strlen(s);
cl(c,);
cl(pos,-);
cl(head,-);
int j,i,loc;
loc = ;
cnt = ;
loop(,j,len)
{
loc = ;
for(i = j;i >= ;--i)
{
int key = s[i]-'a'; insert(loc,key); if(pos[loc] == -)
{
add(i+,j+,);
pos[loc] = i+;
}
else if(pos[loc] < (i+))
{
add(i+,j+,);
add(pos[loc],j+,-);
pos[loc] = i+;
}
}
}
int m,l,r;
scanf("%d",&m);
while(m--)
{
scanf("%d %d",&l,&r);
printf("%d\n",sum(l-,)+sum(len,r)-sum(l-,r)-sum(len,));
} }
return ;
}
这个是dp的。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct list
{
int next;
int v;
}g[];
int head[];
int vis[];
int ct;
char str[];
int c[][];
void add(int x,int &u)
{
for(int i=head[u];i!=-;i=g[i].next)
{
if(x==g[i].v)
{
u=i;return ;
}
}
g[ct].next=head[u];
g[ct].v=x;
head[u]=ct;
u=ct++;
}
int main()
{
int n,p;
int T,i,j;
scanf("%d%*c",&T);
while(T--)
{
ct=;
memset(head,-,sizeof(head));
memset(vis,-,sizeof(vis));
memset(c,,sizeof(c));
gets(str);
n=strlen(str);
for(j=;j<n;j++)
{
p=;
for(i=j;i>=;i--)
{
add(str[i],p);
if(vis[p]==-)
{
vis[p]=i;
c[i][j]++;
}
else if(vis[p]<i)
{
c[i][j]++;
c[vis[p]][j]--;
vis[p]=i;
}
}
}
// for(j=1;j<n;j++)c[0][j]+=c[0][j-1];
for(j=;j<n;j++)
{
for(i=j;i>=;i--)
{
c[i][j]+=c[i+][j]+c[i][j-]-c[i+][j-];
}
}
int q,a,b;
cin>>q;
while(q--)
{
scanf("%d%d%*c",&a,&b);
printf("%d\n",c[a-][b-]);
}
}
return ;
}
hdu 4622 Reincarnation trie树+树状数组/dp的更多相关文章
- hdu 4622 Reincarnation(后缀数组)
hdu 4622 Reincarnation 题意:还是比较容易理解,给出一个字符串,最长2000,q个询问,每次询问[l,r]区间内有多少个不同的字串. (为了与论文解释统一,这里解题思路里sa数组 ...
- HDU 4622 Reincarnation Hash解法详解
今天想学字符串hash是怎么弄的.就看到了这题模板题 http://acm.hdu.edu.cn/showproblem.php?pid=4622 刚开始当然不懂啦,然后就上网搜解法.很多都是什么后缀 ...
- 【树状数组+dp】HDU 5542 The Battle of Chibi
http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...
- HDU 1166 敌兵布阵 (数状数组,或线段树)
题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...
- HDU 6348 序列计数 (树状数组 + DP)
序列计数 Time Limit: 4500/4000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total Subm ...
- hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)
Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- hdu 2227(树状数组+dp)
Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/3 ...
- HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)
题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...
- hdu 4991(树状数组+DP)
Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
随机推荐
- IT架构之IT架构模型——思维导图
参考: [日] 野村综合研究所系统咨询事业本部. 图解CIO工作指南. 周自恒译 人民邮电出版社,2014
- VSync Count 垂直同步
原地址:http://blog.csdn.net/yesy10/article/details/7794556 Unity3D中新建一个场景空的时候,帧速率(FPS总是很低),大概在60~70之间.一 ...
- linux权威指南 简记
/proc 目录,linxu系统以文件形式存放进程信息,这是一个虚拟的文件系统,不占有任何磁盘空间,当读取该文件系统时,系统内核会拦截动作,并动态产生文件与目录的内容 查看该文件夹,会发现很多已数字命 ...
- MEAN实践——LAMP的新时代替代方案(上)
摘要:90 年代,LAMP 曾风靡一时,然而随着需求的变迁和数据流量的激增,LAMP 已不可避免的走下神坛.近日,在 MongoDB Blog 中,Dana Groce 介绍了一个基于新时代架构的实践 ...
- 【剑指offer】和为S的连续整数序列
找到所有和为S的连续整数序列,序列长度>=2 我的思路:数学法,限定首元素范围,计算序列长度. 书上解法:用small和big两个游标记录序列的开始和结束位置,调整游标. 我的解法: /* 直 ...
- LoaderManager使用详解(一)---没有Loader之前的世界
来源: http://www.androiddesignpatterns.com/2012/07/loaders-and-loadermanager-background.html 感谢作者Alex ...
- URAL 1152. False Mirrors (记忆化搜索 状压DP)
题目链接 题意 : 每一颗子弹破坏了三个邻近的阳台.(第N个阳台是与第1个相邻)射击后后的生存的怪物都对主角造成伤害- 如此,直到所有的怪物被消灭,求怎样射击才能受到最少伤害. 思路 : 状压,数据不 ...
- WCF分布式开发步步为赢(5)服务契约与操作重载
继上一节WCF分布式开发步步为赢系列的(4):WCF服务可靠性传输配置与编程开发,本节我们继续学习WCF分布式开发步步为赢的第(5)节:服务契约与操作重载.这里我们首先讲解OOP面向对象的编程中方法重 ...
- Android Grapics图像类体系
- Codeforces Round #335 (Div. 2) A. Magic Spheres 模拟
A. Magic Spheres Carl is a beginner magician. He has a blue, b violet and c orange magic spheres. ...