String

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)

Problem Description
Bob has a dictionary with N words in it.
Now there is a list of words in which the middle part of the word has continuous letters disappeared. The middle part does not include the first and last character.
We only know the prefix and suffix of each word, and the number of characters missing is uncertain, it could be 0. But the prefix and suffix of each word can not overlap.
For each word in the list, Bob wants to determine which word is in the dictionary by prefix and suffix.
There are probably many answers. You just have to figure out how many words may be the answer.

Input
The first line of the input gives the number of test cases T; T test cases follow.
Each test case contains two integer N and Q, The number of words in the dictionary, and the number of words in the list.
Next N line, each line has a string Wi, represents the ith word in the dictionary (0<|Wi|≤100000)
Next Q line, each line has two string Pi , Si, represents the prefix and suffix of the ith word in the list (0<|Pi|,|Si|≤100000,0<|Pi|+|Si|≤100000)
All of the above characters are lowercase letters.
The dictionary does not contain the same words.

Limits
T≤5
0<N,Q≤100000
∑Si+Pi≤500000
∑Wi≤500000

Output
For each test case, output Q lines, an integer per line, represents the answer to each word in the list.

Sample Input
1
4 4
aba
cde
acdefa
cdef
a a
cd ef
ac a
ce f

Sample Output
2
1
1
0

题意:

  给你n个母串,m个询问

  每次询问给你一个前缀,后缀

  问你有多少个母串的前缀,后缀等于当前,且不相交

题解:

  先将所有母串正串,反串排序,那么每个询问的前缀后缀,会对应存在于两段区间

  现在要查询的就是这两个区间同时存在哪些母串数量

  将母串在正串,反串存在的位置x,y看作一个点,查询的看作一个区间,这个就是平面上一个矩阵包含多少个点,用线段树+扫描线解决

  有一种情况是重复的了比如 母串含有 aaa,查询aa aa

  这个时候就遍历重叠的是哪一部分,hash去重就行了

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 5e5+, M = 1e3+,inf = 2e9; const ULL mod = 1004535809ULL;
int n,m,ans[N],t;
struct ss{
string s;
int id;
}a[N],b[N];
string c[N],d[N];
struct Point{
int x,y,id;
bool operator < (const Point &j) const {
if(x == j.x) return y < j.y;
else return x < j.x;
}
}p[N]; bool cmp(ss s1,ss s2) {
return s1.s < s2.s;
}
struct Que{
int top,down,x,type,qid;
bool operator < (const Que &j) const {
if( x == j.x)
return type > j.type;
else return x < j.x;
}
}Q[N]; int sum[N * ];
void build(int i,int ll,int rr) {
sum[i] = ;
if(ll == rr) return ;
build(ls,ll,mid);build(rs,mid+,rr);
}
void update(int i,int ll,int rr,int x) {
if(ll == rr) {
sum[i] += ;
return ;
}
if(x <= mid) update(ls,ll,mid,x);
else update(rs,mid+,rr,x);
sum[i] = sum[ls] + sum[rs];
}
int ask(int i,int ll,int rr,int x,int y) {
if(ll == x && rr == y) return sum[i];
if(y <= mid) return ask(ls,ll,mid,x,y);
else if(x > mid) return ask(rs,mid+,rr,x,y);
else return ask(ls,ll,mid,x,mid) + ask(rs,mid+,rr,mid+,y);
}
map<string ,int > mp;
ULL sqr[N]; void init() {
mp.clear();
for(int i = ; i <= m; ++i) ans[i] = ;
}
int main() {
int T;
sqr[] = 1LL;
for(int i = ; i < N; ++i) sqr[i] = sqr[i-] * mod;
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
init();
for(int i = ; i <= n; ++i) {
cin>>a[i].s;a[i].id = i;
b[i] = a[i];
reverse(b[i].s.begin(),b[i].s.end());
c[i] = a[i].s;
d[i] = b[i].s; mp[c[i]] += ;
}
sort(a+,a+n+,cmp);
sort(b+,b+n+,cmp); for(int i = ; i <= n; ++i)
p[a[i].id].x = i,p[b[i].id].y = i; sort(d+,d+n+);
sort(c+,c+n+);
int cnt = ;
for(int i = ; i <= m; ++i) {
cin>>c[]>>d[];
reverse(d[].begin(),d[].end());
int l = lower_bound(c+,c+n+,c[]) - c;
c[] += ('z'+);
int r = lower_bound(c+,c+n+,c[]) - c - ;
c[].erase(--c[].end());
int l1 = lower_bound(d+,d+n+,d[]) - d; d[] += ('z'+);
int r1 = lower_bound(d+,d+n+,d[]) - d - ;
d[].erase(--d[].end());
reverse(d[].begin(),d[].end());
if(l > r || l1 > r1) ans[i] = ;
else {
++cnt;
Q[cnt].top = r1;
Q[cnt].x = l-;
Q[cnt].down = l1;
Q[cnt].type = -;
Q[cnt].qid = i; ++cnt;
Q[cnt].top = r1;
Q[cnt].x = r;
Q[cnt].down = l1;
Q[cnt].type = ;
Q[cnt].qid = i;
} for(int j = c[].length() - ,k = ; k < d[].length() && c[].begin()!=c[].end(); j = c[].length() - ,++k)
{
// cout<<c[0][j]<<" "<<d[0][k]<<endl;
if(c[][j] == d[][k])
{
c[].erase((--c[].end()));
ans[i] -= mp[c[] + d[]];
}else break;
} }
for(int i = ; i <= n; ++i) {
++cnt;
Q[cnt].top = p[i].y;
Q[cnt].x = p[i].x;
Q[cnt].type = ;
}
build(,,n);
sort(Q+,Q+cnt+);
for(int i = ; i <= cnt; ++i) {
if(Q[i].type == ) {
update(,,n,Q[i].top);
}
if(Q[i].type == ) {
ans[Q[i].qid] += ask(,,n,Q[i].down,Q[i].top);
}
if(Q[i].type == -) {
ans[Q[i].qid] -= ask(,,n,Q[i].down,Q[i].top);
}
}
for(int i = ; i <= m; ++i) {
printf("%d\n",ans[i]);
}
}
return ;
} /*
1
1 1
aaa
aa aa
*/

HDU 6096 String 排序 + 线段树 + 扫描线的更多相关文章

  1. HDU 1828“Picture”(线段树+扫描线求矩形周长并)

    传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...

  2. hdu 1828 Picture(线段树扫描线矩形周长并)

    线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...

  3. HDU 3265 Posters ——(线段树+扫描线)

    第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: #include <stdio.h> #include <algorithm> ...

  4. HDU 5091---Beam Cannon(线段树+扫描线)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...

  5. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  6. 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...

  7. HDU 1828 Picture(线段树扫描线求周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)

    传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...

  9. hdu 3265 Posters(线段树+扫描线+面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 题意:给你一张挖了洞的墙纸贴在墙上,问你总面积有多少. 挖了洞后其实就是多了几个矩形墙纸,一张墙 ...

随机推荐

  1. 九度oj 题目1385:重建二叉树

    题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...

  2. RR隔离级别下通过next-key locks 避免幻影读

    ---恢复内容开始--- mysql innodb目前使用范围最广的两种隔离级别为RC和RR,RR修复了RC中所存在的不可重复读 READ COMMITED 不可重复读 在同一事务中两次查看的结果集不 ...

  3. Terracotta服务器的不同配置方式

    Terracotta服务器的不同配置方式 博客分类: 企业应用面临的问题 Java&Socket 开源组件的应用 Terracotta双机多机镜像服务器阵列分片模式企业应用 Terracott ...

  4. 使用Unity做2.5D游戏教程(二)

    最近在研究Unity 3D,看了老外Marin Todorov写的教程很详细,就翻译过来以便自己参考,翻译不好的地方请多包涵. 这是使用Unity 游戏开发工具制作一个简单的2.5D 游戏系列教程的第 ...

  5. spring之生命周期

    1.容器中对的生命周期 spring可以管理 singleton作用域的bean的生命周期,spring可以精确地知道该bean何时被创建,何时被初始化完成,容器合适准备销毁该bean实例. spri ...

  6. leetcode 347 priority,map的使用

    主要是对次数进行排序,然后去前几个最大次数的值,输出即可 class Solution { public: vector<int> topKFrequent(vector<int&g ...

  7. cf468C Hack it!

    Little X has met the following problem recently. Let's define f(x) as the sum of digits in decimal r ...

  8. properties类的基本使用方法

    properties类的基本使用方法1.假设有“pp.properties”,内容有       age=22       2.java中用下面方法:   Properties   props   = ...

  9. STL学习笔记(一) 容器

    0.前言随机访问迭代器: vector.string.dequeSTL的一个革命性的方面就是它的计算复杂性保证 条款01:慎重选择容器类型 c++提供的容器:标准STL序列容器:vector.stri ...

  10. gdb 远程调试android进程

    原文:http://blog.csdn.net/xinfuqizao/article/details/7955346?utm_source=tuicool 什么是gdb 它是gnu组织开发的一个强大的 ...