[51nod1440]迈克打电话
有n只熊,从1到n进行编号。
第i只熊的电话号码是si。每只熊会给那些电话号码是他的子串的熊打电话(可能会给自己打)。
call(i, j) 表示第i只熊给第j只熊打电话的次数,也就是第j个串在第i个串中出现的次数。
迈克会有q次询问。每个询问中给出L,R,k,然后请您计算一下 sum{call(i,k)},L<=i<=R
Input
第一行包含两个整数n 和 q (1 ≤ n ≤ 2 × 10^5 , 1 ≤ q ≤ 5 × 10^5).
接下来n行,每行一个电话号码,第i行给出第i只熊的电话号码。每个号码只包含英文小写字符,并且非空,所有串的长度之和≤ 2 × 10^5
接下来q行,每行包含l,r,k(1 ≤ l ≤ r ≤ n 并且 1 ≤ k ≤ n)。
Output
对于每一个查询,输出答案并换行。
根据fail链建树,每次的查询变成统计 第l..r个字符串的所有前缀的结束节点 有多少个是在 查询串的结束节点的子树里。
按dfs序随便搞...直接主席树或者离线后树状数组都可以。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
#define ui unsigned int
#define ull unsigned long long
const int maxn=,mxnode=maxn*;
struct zs{int too,pre;}e[maxn];int tott,last[maxn];
int lc[mxnode],rc[mxnode],sm[mxnode],tt,rt[maxn];
int ch[maxn][],tot,pos[maxn],cnt,l[maxn],r[maxn],dl[maxn],fail[maxn];
int l1[maxn],r1[maxn],tim;
int i,j,k,n,m;
int L,R,P,SM;
char s[maxn]; int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
} inline void insert(int a,int b){e[++tott].too=b,e[tott].pre=last[a],last[a]=tott;}
inline void trie(int n){
int p=,i,c;
for(i=;i<=n;i++){
c=s[i]-'a';
if(!ch[p][c])ch[p][c]=++tot,p=tot;else p=ch[p][c];
pos[++cnt]=p;
}
}
inline void getfail(){
int l=,r=,i,now,j,p;dl[]=;
while(l<r){
now=dl[++l];
for(i=;i<;i++)if(ch[now][i]){
dl[++r]=j=ch[now][i];
for(p=fail[now];p&&!ch[p][i];p=fail[p]);
fail[j]=!now?:ch[p][i],insert(fail[j],j);//printf(" %d - - ->%d\n",j,fail[j]);
}
}
} void dfs(int x){
l1[x]=++tim;
for(int i=last[x];i;i=e[i].pre)dfs(e[i].too);
r1[x]=tim;
} void insert(int &x,int pre,int a,int b){
sm[(x=++tt)]=sm[pre]+;
if(a==b)return;
int mid=a+b>>;
if(P<=mid)rc[x]=rc[pre],insert(lc[x],lc[pre],a,mid);
else lc[x]=lc[pre],insert(rc[x],rc[pre],mid+,b);
}
void query(int x,int pre,int a,int b){
if((L<=a&&R>=b)||!x){SM+=sm[x]-sm[pre];return;}
int mid=a+b>>;
if(L<=mid)query(lc[x],lc[pre],a,mid);
if(R>mid)query(rc[x],rc[pre],mid+,b);
} char ss[];int len;
inline void outx(int x){
if(!x){putchar('');return;}
while(x)ss[len++]=x%,x/=;
while(len)putchar(ss[--len]+);
}
int main(){
n=read(),m=read();
for(i=;i<=n;i++)
scanf("%s",s+),l[i]=cnt+,
trie(strlen(s+)),r[i]=cnt;
getfail();
dfs();tot++;
for(i=;i<=cnt;i++)//printf("i:%d dfn:%d\n",i,l1[pos[i]]),
P=l1[pos[i]],insert(rt[i],rt[i-],,tot); int x,y,kk;
while(m--)
x=read(),y=read(),kk=read(),
L=l1[pos[r[kk]]],R=r1[pos[r[kk]]],SM=,query(rt[r[y]],rt[l[x]-],,tot),
// printf(" %d-----%d\n",L,R),
printf("%d\n",SM);
}
[51nod1440]迈克打电话的更多相关文章
- iOS开发之调用系统打电话发短信接口以及程序内发短信
在本篇博客开头呢,先说一下写本篇的博客的原因吧.目前在做一个小项目,要用到在本应用程序内发验证码给其他用户,怎么在应用内发送短信的具体细节想不大起来了,于是就百度了一下,发现也有关于这方面的博客,点进 ...
- Android开发学习——打电话应用
打电话应用 system/app/phone.apk 这个是打电话应用,这个Java API 不允许应用级程序员改写,系统级才可以 system/app/dialer.apk 这个是拨号器应用,可 ...
- 打电话,发短信,发邮件,app跳转
1.打电话 - (IBAction)callPhone1:(id)sender { NSURL *url = [NSURL URLWithString:@"tel://18500441739 ...
- addChildViewController后开启热点/wifi/打电话引起的子vc的布局问题
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Menlo; color: #00b1ff } p.p2 { margin: 0.0px 0. ...
- iOS 打电话 发短信(转载)
官方代码 发短息和邮件添加MessageUI.framework 库 发送信息 - (IBAction)showSMSPicker:(id)sender { // You must check tha ...
- linux下利用GPRS模块发短信、打电话
一.开发环境 内核版本:linux-3.0 开发板:FL2440(nandflash:K9F1G08 128M) GPRS模块:SIM900 二.与发短信和拨号相关的 AT 指 ...
- iOS中如何切换到发短信、打电话、发邮件
我们在做APP的时候,难免会遇到需要调用短信,电话等程序的时候.如美团. 当然,这些都只是一些简单的方法就可以实现,但是时间久了也会淡忘,所以想写这边博客.一是为了再捡起来复习一下,另一个相当于留个备 ...
- iOS开发中打电话发短信等功能的实现
在APP开发中,可能会涉及到打电话.发短信.发邮件等功能.比如说,通常一个产品的"关于"页面,会有开发者的联系方式,理想情况下,当用户点击该电话号码时,能够自动的帮用户拨出去,就涉 ...
- ios 设置亮度、声音;调用发短信、邮件、打电话
一,设置亮度 [[UIScreen mainScreen] setBrightness:0.5];//0.0~1.0 二,设置声音 1,添加 MediaPlayer.framework 框架 2,在需 ...
随机推荐
- 关于Sublime Text编辑器的实用技巧
本文转载至一篇博文,为您提供Sublime Text编辑器的12个技巧和诀窍,深入挖掘这个看似简洁的代码编辑器,背后所隐藏的实现各种高级功能的无限可能. 1) 选择 以下是一些Sublime Text ...
- df 命令详解
一.df 作用: 显示磁盘分区上的可使用的磁盘空间, 默认显示单位为kb . 可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间的等信息. 选项: -a :包含全部的文件系统 -h :以 ...
- 聚簇(或者叫做聚集,cluster)索引和非聚簇索引
字典的拼音目录就是聚簇(cluster)索引,笔画目录就是非聚簇索引.这样查询“G到M的汉字”就非常快,而查询“6划到8划的字”则慢. 聚簇索引是一种特殊索引,它使数据按照索引的排序顺序存放表中.聚簇 ...
- Linux发行版 CentOS6.5 修改默认主机名
修改前准备 我们将主机名修改为comexchan.cnblogs.com(本文发布于http://comexchan.cnblogs.com/) 备份相关配置文件,以便回滚 cp /etc/sysco ...
- 使用line-height来垂直居中在安卓设备并不居中,利用ji调整
先判断智能机浏览器的版本信息:方法有两种,但是第一种兼容性更好,但是使用了device插件 第一种: if (device.android()){ } 第二种: var ua = navigator. ...
- 【算法设计与分析基础】24、kruskal算法详解
首先我们获取这个图 根据这个图我们可以得到对应的二维矩阵图数据 根据kruskal算法的思想,首先提取所有的边,然后把所有的边进行排序 思路就是把这些边按照从小到大的顺序组装,至于如何组装 这里用到并 ...
- webpack3.x基本配置与总结
基本配置 1.开始之前,请确定你已经安装了当前 Node 的较新版本. 2.然后在文件夹根目录下执行以下命令初始化项目并全局安装webpack: 1.$ cnpm init // 初始化项目 2.$ ...
- 使用Word进行文档修订版本的比较
项目经理在实际的工作过程中,比如要写文档方案,就需要对文档的修订版本进行管理和控制.在以前的工作中,笔者使用的是UltraEdit这个软件工具中的Ultra Compare这个子工具来进行的文档版本的 ...
- vim置于后台,vim 编辑多文件
这里介绍一个很实用的方法:1.将vim置于后台,直接按 ctrl + z可以将当前的vim置于后台 2.然后可以去别的目录再打开一个 当你需要打开之前的vim的时候3.打jobs命令看当前有哪些vim ...
- SQL重复记录查询的几种方法
http://www.jb51.net/article/34820.htm \ 1.查找表中多余的重复记录,重复记录是根据单个字段(peopleId)来判断 复制代码 代码如下: select * f ...