思路:

网上的题解有AC自动机的,有trie树的,还有(乱搞?)的

首先把输入的那n个串按照字典序排序,

把n个串翻转以后再按照字典序排序

这样我们发现, 查的前缀在字典序排序后是一段区间,

查的后缀翻转一下在翻转后的字典序排序以后也是一段区间

这样如果不考虑重叠的问题,就是一个简单的二维数点问题,一维排序,一维线段树即可解决

如果有重叠的问题,我们需要搞出来每个字符串的长度,使给出的前缀长+后缀长>=原字符串长度

此时题目变成了三维偏序,排序后树套树即可。

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int N=;
int cases,n,q,root[N<<],cnt,tree[N*],lson[N*],rson[N*];
struct Node{string str;int id,len;}X[N],Y[N],tmp;
bool operator<(Node a,Node b){return a.str<b.str;}
struct Pnt{int x,y,z;}p[N];
struct Ask{int xl,xr,yl,yr,z,id,ans;}ask[N];
bool cmp1(Pnt a,Pnt b){return a.z>b.z;}
bool cmp2(Ask a,Ask b){return a.z>b.z;}
bool cmp3(Ask a,Ask b){return a.id<b.id;}
void Insert(int l,int r,int &pos,int wei){
if(!pos)pos=++cnt;tree[pos]++;
if(l==r)return;
int mid=(l+r)>>;
if(mid>=wei)Insert(l,mid,lson[pos],wei);
else Insert(mid+,r,rson[pos],wei);
}
void insert(int l,int r,int pos,int num,int wei){
Insert(,n,root[pos],wei);
if(l==r)return;
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
if(mid<num)insert(mid+,r,rson,num,wei);
else insert(l,mid,lson,num,wei);
}
int Query(int l,int r,int pos,int L,int R){
if(l>=L&&r<=R)return tree[pos];
int mid=(l+r)>>;
if(mid<L)return Query(mid+,r,rson[pos],L,R);
else if(mid>=R)return Query(l,mid,lson[pos],L,R);
else return Query(l,mid,lson[pos],L,R)+Query(mid+,r,rson[pos],L,R);
}
int query(int l,int r,int pos,int xl,int xr,int yl,int yr){
if(l>=xl&&r<=xr)return Query(,n,root[pos],yl,yr);
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
if(mid<xl)return query(mid+,r,rson,xl,xr,yl,yr);
else if(mid>=xr)return query(l,mid,lson,xl,xr,yl,yr);
else return query(l,mid,lson,xl,xr,yl,yr)+query(mid+,r,rson,xl,xr,yl,yr);
}
int main(){
ios::sync_with_stdio(false);
cin>>cases;
while(cases--){
memset(tree,,sizeof(int)*(cnt+));
memset(lson,,sizeof(int)*(cnt+));
memset(rson,,sizeof(int)*(cnt+));
memset(root,,sizeof(root));cnt=;
cin>>n>>q;
for(int i=;i<=n;i++)cin>>X[i].str;
sort(X+,X++n);
for(int i=;i<=n;i++)X[i].id=i,X[i].len=X[i].str.length();
for(int i=;i<=n;i++)Y[i]=X[i];
for(int i=;i<=n;i++)reverse(Y[i].str.begin(),Y[i].str.end());
sort(Y+,Y++n);
for(int i=;i<=n;i++)p[i].x=Y[i].id,p[i].y=i,p[i].z=Y[i].len;
for(int i=;i<=q;i++){
string pre,suf;cin>>pre>>suf;
ask[i].id=i;tmp.str=pre;
ask[i].xl=lower_bound(X+,X++n,tmp)-X;
tmp.str=pre,tmp.str.push_back('z'+);
ask[i].xr=lower_bound(X+,X++n,tmp)-X-;
tmp.str=suf,reverse(tmp.str.begin(),tmp.str.end());
ask[i].yl=lower_bound(Y+,Y++n,tmp)-Y;
tmp.str.push_back('z'+);
ask[i].yr=lower_bound(Y+,Y++n,tmp)-Y-;
ask[i].z=pre.size()+suf.size();
}
sort(p+,p++n,cmp1);sort(ask+,ask++q,cmp2);
int tt=;
for(int i=;i<=q;i++){
while(p[tt].z>=ask[i].z&&tt<=n)insert(,n,,p[tt].x,p[tt].y),tt++;
if(ask[i].xl>ask[i].xr||ask[i].yl>ask[i].yr){ask[i].ans=;continue;}
ask[i].ans=query(,n,,ask[i].xl,ask[i].xr,ask[i].yl,ask[i].yr);
}sort(ask+,ask++q,cmp3);
for(int i=;i<=q;i++)cout<<ask[i].ans<<endl;
}
}

HDU 6096 树套树的更多相关文章

  1. hdu 4417 Super Mario/树套树

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意很简单,给定一个序列求一个区间 [L, R,]中小于等于H的元素的个数. 好像函数式线段树可 ...

  2. hdu 4819 Mosaic 树套树 模板

    The God of sheep decides to pixelate some pictures (i.e., change them into pictures with mosaic). He ...

  3. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6050  Solved: 2007[Submit][Sta ...

  4. BZOJ4170 极光(CDQ分治 或 树套树)

    传送门 BZOJ上的题目没有题面-- [样例输入] 3 5 2 4 3 Query 2 2 Modify 1 3 Query 2 2 Modify 1 2 Query 1 1 [样例输出] 2 3 3 ...

  5. bzoj3262: 陌上花开(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  6. bzoj3295: [Cqoi2011]动态逆序对(树套树)

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  7. BZOJ 3110 k大数查询 & 树套树

    题意: 有n个位置,每个位置可以看做一个集合,现在要求你实现一个数据结构支持以下功能: 1:在a-b的集合中插入一个数 2:询问a-b集合中所有元素的第k大. SOL: 调得火大! 李建说数据结构题能 ...

  8. BZOJ 3110 树套树 && 永久化标记

    感觉树套树是个非常高深的数据结构.从来没写过 #include <iostream> #include <cstdio> #include <algorithm> ...

  9. 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...

随机推荐

  1. jmeter的线程组执行顺序不以其出现的顺序发生变化

    jmeter可以同时配置多个线程组,那么他们的执行顺序是什么呢?和他们出现的顺序有什么关系呢? 先说下几个特殊的线程组:tearDown线程组和setUp线程组,tearDown线程组一定在最后执行, ...

  2. linux 查找目录下的文件内容并替换(批量)

    2.sed和grep配合 命令:sed -i s/yyyy/xxxx/g `grep yyyy -rl --include="*.txt" ./` 作用:将当前目录(包括子目录)中 ...

  3. Material UI:很强大的CSS框架

    Material UI 是一款功能很强大,界面却十分清新简洁的CSS框架.Material UI利用了Google的Material Design 全新设计语言.而且让每个UI组件都变得很独立.因此开 ...

  4. python的线程thread笔记

    python的线程是用thread和threading来实现的.其中利用threading会更好,因为thread没有线程保护,当主线程退出了之后,子线程也会被强行退出.threading支持守护线程 ...

  5. 自定义的强大的UITableViewCell

    UITableView的强大更多程度上来自于可以任意自定义UITableViewCell单元格.通常,UITableView中的Cell是动态的,在使用过程中,会创建一个Cell池,根据每个cell的 ...

  6. [转] logback 常用配置详解(序)logback 简介

    转载文章:原文出处:http://aub.iteye.com/blog/1101222 logback 简介 Ceki Gülcü在Java日志领域世界知名.他创造了Log4J ,这个最早的Java日 ...

  7. javaScript定义函数的三种方式&amp;变量的作用域

    一.函数定义 方式1.普通方式定义函数 function 函数名(參数n){ 函数体 } function add(a,b){ return a+b; } 方式2.直接量定义函数 var 函数名=fu ...

  8. button和submit区别

    type=button      就单纯是按钮功能 type=submit      是发送表单 但是对于从事WEB UI的人应该要注意到,使用submit来提高页面易用性: 使用submit后,页面 ...

  9. Java 解析excel2003和2007区别和兼容性问题(POI操作)

    最近在使用POI对excel操作中发现一些问题,2003和2007的区别还是蛮大的: 2007相关的包: poi-3.9.jar poi-examples-3.8.jar poi-excelant-3 ...

  10. Tju 4119. HDFS

    4119.   HDFS Time Limit: 5.0 Seconds   Memory Limit: 5000KTotal Runs: 225   Accepted Runs: 77 In HDF ...