题意:给你一个字符串和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的更多相关文章

  1. hdu 4622 Reincarnation(后缀数组)

    hdu 4622 Reincarnation 题意:还是比较容易理解,给出一个字符串,最长2000,q个询问,每次询问[l,r]区间内有多少个不同的字串. (为了与论文解释统一,这里解题思路里sa数组 ...

  2. HDU 4622 Reincarnation Hash解法详解

    今天想学字符串hash是怎么弄的.就看到了这题模板题 http://acm.hdu.edu.cn/showproblem.php?pid=4622 刚开始当然不懂啦,然后就上网搜解法.很多都是什么后缀 ...

  3. 【树状数组+dp】HDU 5542 The Battle of Chibi

    http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...

  4. HDU 1166 敌兵布阵 (数状数组,或线段树)

    题意:... 析:可以直接用数状数组进行模拟,也可以用线段树. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000&quo ...

  5. HDU 6348 序列计数 (树状数组 + DP)

    序列计数 Time Limit: 4500/4000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Subm ...

  6. hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

    Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  7. hdu 2227(树状数组+dp)

    Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/3 ...

  8. HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

    题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...

  9. hdu 4991(树状数组+DP)

    Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

随机推荐

  1. jQuery1.9.1--结构及$方法的工作原理源码分析

    jQuery的$方法使用起来非常的多样式,接口实在太灵活了,有点违反设计模式的原则职责单一.但是用户却非常喜欢这种方式,因为不用记那么多名称,我只要记住一个$就可以实现许多功能,这个$简直就像个万能的 ...

  2. Random的用法

    import java.util.Random; public class RandomTest { public static void main(String[] args) { Random r ...

  3. tomcat 跨域

    http://www.360doc.com/content/14/0920/14/7909375_411017244.shtml http://www.tuicool.com/articles/Znq ...

  4. POJ 1300 Door Man(欧拉回路的判定)

    题目链接 题意 : 庄园有很多房间,编号从0到n-1,能否找到一条路径经过所有开着的门,并且使得通过门之后就把门关上,关上的再也不打开,最后能回到编号为0的房间. 思路 : 这就是一个赤裸裸的判断欧拉 ...

  5. zoj 2686 Cycle Game 博弈论

    其实规律很好找的,当从某点开始,向某一边找出非0的个数,为奇数时必胜. 代码如下: #include<iostream> #include<cstdio> using name ...

  6. Android View体系

  7. 小奇模拟赛9.13 by hzwer

    2015年9月13日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...

  8. Java7编程 高级进阶学习笔记--嵌套类

    定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...

  9. CreateProcess启动隐藏的外部程序(其实就是CreateDesktop,然后指定STARTUPINFO.lpDesktop)

    HDESK hDesk = CreateDesktop(_T("MyDesk"), NULL, NULL, 0, GENERIC_ALL, NULL); ASSERT(hDesk) ...

  10. JavaWeb笔记——三大组件之监听器

    1 JavaWeb监听器概述 在JavaWeb被监听的事件源为:ServletContext.HttpSession.ServletRequest,即三大域对象. l  监听域对象“创建”与“销毁”的 ...