正题

题目链接:https://ac.nowcoder.com/acm/contest/72/F


题目大意

\(n\)个字符串,包括小写字母和\(\#\)。其中\(\#\)可以替换为任意字符串。求有多少对字符串可能相同。

保证每个字符串至少有一个\(\#\)。

\(2\leq n\leq 500000,\sum_{i=1}^n |s_i|\leq 10^6\)


解题思路

因为可以替换为任意字符串,所以只需要考虑第一个\(\#\)前和最后一个\(\#\)后的部分。

在仔细考虑一下,这个字符串分成前后的两个部分\(s,t\)。数对\((x,y)\)满足条件当且仅当\(s_x\)是\(s_y\)的前缀,或者\(s_y\)是\(s_x\)的前缀,且\(t_x\)是\(t_y\)的后缀,或者\(t_y\)是\(t_x\)的后缀。

放到两棵\(Trie\)树上就是都有祖先关系就好了,直接跑第一棵上,然后用两个树状数组在第二棵树上维护就好了。

时间复杂度\(O(m\log m)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lowbit(x) (x&-x)
using namespace std;
const int N=1e6+10;
int n,cnt,pos[N],dfn[N],ed[N];
long long ans;char s[N];
vector<int> G[N];
struct TreeBinary{
int t[N];
void Change(int x,int val){
while(x<=cnt){
t[x]+=val;
x+=lowbit(x);
}
return;
}
int Ask(int x){
int ans=0;
while(x){
ans+=t[x];
x-=lowbit(x);
}
return ans;
}
}Bf,Bs;
struct Trie{
int t[N][26],m=1;
int Insert(char *s,int n){
int x=1;
for(int i=1;i<=n;i++){
if(s[i]=='#')break;
int c=s[i]-'a';
if(!t[x][c])t[x][c]=++m;
x=t[x][c];
}
return x;
}
}Tp,Ts;
void dfs(int x){
dfn[x]=++cnt;
for(int i=0;i<26;i++)
if(Ts.t[x][i])
dfs(Ts.t[x][i]);
ed[x]=cnt;
}
void work(int x){
for(int i=0;i<G[x].size();i++){
int p=G[x][i];ans+=Bf.Ask(dfn[pos[p]]);
Bf.Change(dfn[pos[p]],1);Bf.Change(ed[pos[p]]+1,-1);
ans+=Bs.Ask(ed[pos[p]])-Bs.Ask(dfn[pos[p]]);
Bs.Change(dfn[pos[p]],1);
}
for(int i=0;i<26;i++)
if(Tp.t[x][i])
work(Tp.t[x][i]);
for(int i=0;i<G[x].size();i++){
int p=G[x][i];Bs.Change(dfn[pos[p]],-1);
Bf.Change(dfn[pos[p]],-1);Bf.Change(ed[pos[p]]+1,1);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
int l=strlen(s+1);
int x=Tp.Insert(s,l);
G[x].push_back(i);
reverse(s+1,s+1+l);
pos[i]=Ts.Insert(s,l);
}
dfs(1);
work(1);
printf("%lld\n",ans);
return 0;
}

Wannafly挑战赛10F-小H和遗迹【Trie,树状数组】的更多相关文章

  1. 【bzoj4548】小奇的糖果 STL-set+树状数组

    题目描述 平面上有n个点,每个点有一种颜色.对于某一条线段,选择所有其上方或下方的点.求:在不包含所有颜色的点的前提下,选择的点数最多是多少.(本题中如果存在某颜色没有相应的点,那么选择任何线段都不算 ...

  2. wannafly 挑战赛10 小H和游戏

    题解: 先利用dfs找出各个节点之间的关系.然后利用一个sum[i][j] 数组  sum[i][0] 表示i这个节点收到影响的次数 sum[i][1]表示i这个节点的儿子们收到影响的次数 sum[i ...

  3. wannafly 挑战赛10 小H和密码

    题意:中文题就不解释了 题解: dp[i][j]表示前i 个轮盘 和一个字符串前j 个字符的匹配情况 ,具体的状态转移解释见代码 #include <cstdio> #include &l ...

  4. 2019.01.21 bzoj2441: [中山市选2011]小W的问题(树状数组+权值线段树)

    传送门 数据结构优化计数菜题. 题意简述:给nnn个点问有多少个www型. www型的定义: 由5个不同的点组成,满足x1<x2<x3<x4<x5,x3>x1>x2 ...

  5. H - 逆序数(树状数组)

    在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...

  6. 算法笔记求序列A每个元素左边比它小的数的个数(树状数组和离散化)

    #include <iostream> #include <algorithm> #include <cstring> using namespace std ; ...

  7. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  8. 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治

    LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...

  9. hdu 4217 Data Structure? 树状数组求第K小

    Data Structure? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

随机推荐

  1. Unity遮罩之Mask、RectMask2D与Sprite Mask适用场景分析

    遮罩,顾名思义是一种可以掩盖其它元素的控件.常用于修改其它元素的外观,或限制元素的形状.比如ScrollView或者圆头像效果都有用到遮罩功能.本系列文章希望通过阅读UGUI源码的方式,来探究遮罩的实 ...

  2. 接口和包--Java学习笔记

    接口 定义及基础用法 interface定义:没有字段的抽象类 interface person{ void hello(); String getName(); } /*接口本质上就是抽象类 abs ...

  3. springboot分页插件的使用

    在springboot工程下的pom.xml中添加依赖 <!--分页 pagehelper --> <dependency> <groupId>com.github ...

  4. C++面试题(四)——智能指针的原理和实现

    C++面试题(一).(二)和(三)都搞定的话,恭喜你来到这里,这基本就是c++面试题的最后一波了.     1,你知道智能指针吗?智能指针的原理.     2,常用的智能指针.     3,智能指针的 ...

  5. SpringBoot2.0整合Quartz定时任务(持久化到数据库,更为简单的方式)

    1. pom文件添加依赖 <dependencies> <dependency> <groupId>org.springframework.boot</gro ...

  6. Qt 中事件与处理

    一.事件与处理程序在运算过程中发生的一些事情:鼠标单击.键盘的按下...这些的事件的监控与处理在Qt中不是以信号的方式处理的.当这些事件发生时会调用QObject类中的功能函数(虚函数),所有的控件类 ...

  7. Contos 7.x 中Docker安装以及使用

    Docker是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中, 然 ...

  8. 使用javascript纯前端导出excel

    前言(感谢技术的分享者) 参考博客地址 github地址 由SheetJS出品的js-xlsx是一款非常方便的只需要纯JS即可读取和导出excel的工具库,功能强大,支持格式众多,支持xls.xlsx ...

  9. 12-SpringCloud GateWay

    GateWay和Zuul说明 Zuul开发人员窝里斗,实属明日黄花 重点关注Gate Way GateWay是什么 上一代zuul 1.x官网 Gateway官网 概述 Cloud全家桶中有个很重要的 ...

  10. Git工具的使用教程二

    1.3时光穿梭机--版本回退 版本回退分为两步骤进行操作: 步骤: 1.查看版本,确定需要回到的时候点     指令:             git log             git log ...