HDU 6096 String 排序 + 线段树 + 扫描线
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 排序 + 线段树 + 扫描线的更多相关文章
- HDU 1828“Picture”(线段树+扫描线求矩形周长并)
传送门 •参考资料 [1]:算法总结:[线段树+扫描线]&矩形覆盖求面积/周长问题(HDU 1542/HDU 1828) •题意 给你 n 个矩形,求矩形并的周长: •题解1(两次扫描线) 周 ...
- hdu 1828 Picture(线段树扫描线矩形周长并)
线段树扫描线矩形周长并 #include <iostream> #include <cstdio> #include <algorithm> #include &l ...
- HDU 3265 Posters ——(线段树+扫描线)
第一次做扫描线,然后使我对线段树的理解发生了动摇= =..这个pushup写的有点神奇.代码如下: #include <stdio.h> #include <algorithm> ...
- HDU 5091---Beam Cannon(线段树+扫描线)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
- HDU 1828 Picture(线段树扫描线求周长)
Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- HDU 1542"Atlantis"(线段树+扫描线求矩形面积并)
传送门 •题意 给你 n 矩形,每个矩形给出你 $(x_1,y_1),(x_2,y_2)$ 分别表示这个矩形的左下角和右上角坐标: 让你求这 n 个矩形并的面积: 其中 $x \leq 10^{5} ...
- hdu 3265 Posters(线段树+扫描线+面积并)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 题意:给你一张挖了洞的墙纸贴在墙上,问你总面积有多少. 挖了洞后其实就是多了几个矩形墙纸,一张墙 ...
随机推荐
- TOJ 4008 The Leaf Eaters
|A∪B∪C|=|A|+|B|+|C|-|A∩B|-|A∩C|-|B∩C|+|A∩B∩C| 这个是集合的容斥,交集差集什么的,这个在概率论经常用到吧 4008: The Leaf Eaters T ...
- 九度oj 题目1109:连通图
题目描述: 给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的. 输入: 每组数据的第一行是两个整数 n 和 m(0<=n<=1000).n 表示图的顶点数目,m 表示图中边的 ...
- Android开发之(1)AnimationListener
1,就像Button控件有监听器一样,动画效果也有监听器,只需要实现AnimationListener就可以实现对动画效果的监听,只需要实现AnimationListener就可以实现对动画效果的监听 ...
- Codeforces 667C Reberland Linguistics【DFS】
一道卡题意的题. 题目链接: http://codeforces.com/problemset/problem/667/C 题意: 一个串可以看成一个长度大于4的根,加上其后面的若干个相邻(in a ...
- Codeforces 86D Powerful array (莫队算法)
题目链接 Powerful array 给你n个数,m次询问,Ks为区间内s的数目,求区间[L,R]之间所有Ks*Ks*s的和. $1<=n,m<=200000, 1<=s< ...
- CS Academy #32 G
题意: 分析: 考虑如何求方案数 dp[i][j]表示i个数字的和为j的方案数,这是个经典问题,转移有两种,一个是填一个数字1,一个是整体加1 然后这个问题并不是求方案数,而是求对应的权值和 我们很容 ...
- String的引用传递
一 引用传递的三个范例 范例一 package com.mtzsoft; /** * 范例一 * * @author Administrator * */ public class Test1 { p ...
- Hadoop三种模的安装配置过程
JDK+Hadoop安装配置.单机模式配置 以下操作在SecureCRT里面完成 1.关闭防火墙 firewall-cmd --state 显示防火墙状态running/not running sys ...
- javafx中多场景的切换
0.前言 前段时间在做javafx的应用程序,遇到一些坑.以本文记录之.(如有更好的解决办法欢迎评论,本人小白,轻喷) 1.问题 按照官方的中文文档,成功的运行了单一界面的表单登录.于是想自己试试多界 ...
- IOS常见错误分析解决(一直更新) 你值得收藏-综合贴
-来自收藏总结 综合了好多的常见错误 1:clang failed with exit code 254 一:检測代码中 是否 有 NSLog 打印了 返回 void 的值. 2:Verify exi ...