正题

题目链接: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. VMware + LInux + Xshell 连接环境设置

    一.安装好Centos后,打开设置: 网络连接四中模式桥接模式.NAT模式.仅主机和自定义模式: 1).桥接模式:更公司的局域网连接,等于另一台连接进公司的新电脑 2).NAT模式:与虚拟机使用的计算 ...

  2. 【ArcGIS】 设置管段的流向

    在排水管网或者燃气管网中对管段进行几何网络分析,常常用到设置管段流向,一般有三种方法: 1,有流向字段的,直接进行唯一值渲染, 2,没有流向字段的需要建立几何网络, 2.1 在几何网络存在的情况下,设 ...

  3. C语言格式化输出语句

    %d:带符号十进制整数 : %c:单个字符: %s:字符串: %f:6位小数:float; %.2f表示小数点后精确到两位 %lf:6位小数:double;

  4. (3)hadoop单节点配置

    hadopp版本hadoop-2.6.0-cdh5.7.0      下载地址http://archive-primary.cloudera.com/cdh5/cdh/5/ 同样使用flashFXP上 ...

  5. springcloud<zuul过滤器简单配置与跨域设置>

    package com.wangbiao.config; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.Req ...

  6. 学习小记: Kaggle Learn - Machine Learning Explainability

    Method Feature(s) Sample(s) Result Value/Feature Permutation Importance 1 all validation samples Sin ...

  7. x和y为正整数变量,求满足 x+y | xy 的通解。

    x和y为正整数变量,求满足 x+y | xy 的通解. 解:由题设可知存在正整数t满足t(x+y)=xy. 设m=(x,y),则存在正整数u和v满足: x=mu, y=mv, (u,v)=1. 于是有 ...

  8. shell条件语句if

    1.单分支语句 if [ ];then 命令 fi if [ ] then 命令 fi 2.双分支语句 if [ ] then echo cmd1 else echo cmd2 fi 3.多分支语句 ...

  9. 20210718 noip19

    考场 去年考过这场,心态直接爆炸 T1 一眼 T2 当初是我讲的,基本都记得(flag) T3 只记得是树形 DP,但觉得 rush 完前两题后用大量时间应该能搞出来 结果 T2 写了好久,还写假了. ...

  10. WPF Prism8.0中注册Nlog日志服务

    无论是Nlog还是Serilog, 它们都提供了如何快速在各类应用程序当中的快速使用方法. 尽管,你现在无论是在WPF或者ASP.NET Core当中, 都可以使用ServiceCollection来 ...