HDU 6096 树套树
思路:
网上的题解有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 树套树的更多相关文章
- hdu 4417 Super Mario/树套树
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意很简单,给定一个序列求一个区间 [L, R,]中小于等于H的元素的个数. 好像函数式线段树可 ...
- hdu 4819 Mosaic 树套树 模板
The God of sheep decides to pixelate some pictures (i.e., change them into pictures with mosaic). He ...
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- 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 ...
- bzoj3262: 陌上花开(树套树)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- bzoj3295: [Cqoi2011]动态逆序对(树套树)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- BZOJ 3110 k大数查询 & 树套树
题意: 有n个位置,每个位置可以看做一个集合,现在要求你实现一个数据结构支持以下功能: 1:在a-b的集合中插入一个数 2:询问a-b集合中所有元素的第k大. SOL: 调得火大! 李建说数据结构题能 ...
- BZOJ 3110 树套树 && 永久化标记
感觉树套树是个非常高深的数据结构.从来没写过 #include <iostream> #include <cstdio> #include <algorithm> ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树套树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 这题调了我相当长的时间,1wa1a,我是第一次写树套树,这个是树状数组套splay,在每个区间 ...
随机推荐
- eclipse设置全局编码为UTF-8的方法
1.windows->Preferences...打开"首选项"对话框,左侧导航树,导航到general->Workspace,右侧Text file encoding ...
- chrome插件vimium的安装和使用
vimium工具的作用:使你脱离鼠标,使用键盘方便操作页面,默认对所有网站生效 1.chrome商店里有的,但是,我怎么安装,都不行 2.源码安装:http://vimium.github.io/ h ...
- topcoder srm 552
div1 250pt: 题意:用RGB三种颜色的球摆N层的三角形,要求相邻的不同色,给出RGB的数量,问最多能摆几个 解法:三种颜色的数量要么是全一样,要么是两个一样,另外一个比他们多一个,于是可以分 ...
- Edmonds 开花算法
Edmonds 开花算法 input: 图G,匹配M,未饱和点u idea: 查找从 u 開始的 M-交错路径.对每一个顶点记录父亲节点. 发现花朵.则收缩. 维护 S 和 T.S 表示沿着已经饱和的 ...
- Zookeeper 3.4 官方文档翻译
说明 个人英语水平非常一般,理解可能有偏差,假设有翻译不恰当之处,请看官指点. 1.简单介绍 分布式系统就像动物园.当中每台server就像一仅仅动物,Zookeeper就像动物园管理员,协调.服务于 ...
- 查看android-support-v4.jar引出的问题
1.前面博文里也写过如何关联android-support-v4.jar的源码 今天新项目用上述方法的时候,竟然不成功..来回反复试了很长时间,最后发现 新建项目,会自动引用一个类库(自动新建的..) ...
- OutputStream和InputStream的区别 + 实现java序列化
我们所说的流,都是针对内存说的,比如为什么打印到屏幕上就是System.out.println();而从屏幕等待用户输入的却是System.in呢?因为对于内存来说,把字符串打印到屏幕上是从内存流向屏 ...
- 现在企业流行的java框架技术
我将简短分析被用于支持这些框架的企业开发环境或工具箱,例如Borland JBuilder,Eclipse以及BEA Workbench.请记住,市场上有许多有关这些开发框架的图书;然而,在任何一篇文 ...
- cocos2d-x 打包成so文件之后,假设出现错误,能够使用ndk-stack来查看里面的异常
cocos2d-x 打包成so文件之后,假设出现错误,能够使用ndk-stack来查看里面的异常 详细方法.自行百度.
- 谈谈对redux的认识
redux是从flux演变而来,但又独立于react.简言之就是,redux是一种单纯的状态管理器.可以和react搭配,也可以和其它框架搭配. redux有三个重要的部分组成: store, act ...