暂无链接

巧克力

【问题描述】

小 T 有NNN块巧克力,每块巧克力上都有一句话(由小写英文字母组成,不含标点)。现在每块巧克力都断成了若干截,更糟糕的是,有一些碎片丢失了,但是剩下的碎片之间的顺序是可以辨识的。
形式化地,我们用一个只含小写字母和#\##的字符串来代表一块巧克力,其中#表示该位置断开了,可能缺失了一段字符,也可能没有。
例如:如果我们用a#aa\#aa#a来表示一块巧克力,则原来它上面的话可能是aaaaaa,也可能是aaaaaaaaa,aaczraaaaczraaaaczraa 等等,但不会是aabaabaab。
现在小 T 想知道,对于这NNN块巧克力,有多少对满足原来它们上面的话可能是相同的。
保证代表每块巧克力的字符串都至少包含一个#\## 。
注意:形如(x,y),(y,x)(x,y),(y,x)(x,y),(y,x),且满足x≠yx≠yx̸​=y的巧克力对只被计入一次答案,形如(x,x)(x,x)(x,x)的句子对不计入答案,具体可以参见样例。

【输入格式】

输入第一行,一个正整数NNN。
接下来NNN行,每行一个字符串,意义如题所述。

【输出格式】

一个非负整数,表示你给出的答案。

【输入输出样例 1】
chocolate. in

3
a#a
#
aczra#

chocolate.out

3

【输入输出样例说明 1】

有效的巧克力对有:(1,2),(1,3),(2,3)(1,2),(1,3),(2,3)(1,2),(1,3),(2,3)。

【数据范围与约定】

对于所有的数据:2≤N≤500,0002≤N≤500,0002≤N≤500,000,所有字符串的总长不超过1,000,0001,000,0001,000,000。
对于每个子任务的特殊限制:
Subtask1(12pts): 满足性质①;
所有字符串长度相等;
Subtask2(20pts): 满足性质①;
Subtask3(23pts): N≤1,000N≤1,000N≤1,000;
Subtask4(45pts): 无特殊限制;
性质①:每个字符串包含恰好一个#\##,且这个#\##在字符串的开头。

题解

发现只有第一个#\##之前的前缀,和最后一个#\##之后的后缀无法用#\##填补,当两个串其中一个的前缀是另一个串的前缀,一个的后缀是另一个的后缀时,两个字符串可能相同。

所以我们先把所有前缀插入一个Trie\mathcal{Trie}Trie树里,把所有后缀插入另一个Trie\mathcal{Trie}Trie树。

之后在前缀树上dfsdfsdfs,遇到一个前缀的答案统计一次答案,再将该点对应的后缀树中的点点权+1+1+1;统计答案为求后缀树中的子树和以及点到根节点的路径和;回溯时将加上的点权去掉。

由于我们将前缀树dfsdfsdfs路径上在后缀树中对应的点都加了一,那么后缀树中加了一的点一定满足这些串的前缀是当前节点代表的串的前缀的前缀;后缀树子树中的点表示当前串为别的串的后缀的后缀,点到根的路径上的点的是当前串的后缀。

为了求子树和与点到根的路径和,我们需要两颗树状数组,前者用普通的dfsdfsdfs序即可统计,后者需要区间加与单点求值。

代码
#include<bits/stdc++.h>
#define lb(x) (x&-x)
#define pos suf[pre[v][i]]
using namespace std;
const int main_stack = 16;
char my_stack[128<<20];
const int M=1e6+5,N=5e5+5;
char ch[M];
int suf[M],dfn[M],ri[M],df,n;
long long ans;
vector<int>pre[M];
struct BIT{int sum[M];void add(int v,int d){for(;v<=df;v+=lb(v))sum[v]+=d;}void add(int l,int r,int d){add(l,d),add(r+1,-d);}int ask(int v){int ans=0;for(;v;v-=lb(v))ans+=sum[v];return ans;}int ask(int l,int r){if(l>r)return 0;return ask(r)-ask(l-1);}
}bit[2];
struct TRIE{int son[M][27],tot;int ins(int s,int e,int d){int v=0,nxt;for(int i=s;i!=e;i+=d){nxt=ch[i]-'a';if(!son[v][nxt])son[v][nxt]=++tot;v=son[v][nxt];}return v;}
}trie[2];
void dfs1(int v){dfn[v]=++df;for(int i=0;i<26;++i)if(trie[1].son[v][i])dfs1(trie[1].son[v][i]);ri[v]=df;}
void dfs2(int v)
{for(int i=pre[v].size()-1;i>=0;--i)ans+=bit[0].ask(dfn[pos])+bit[1].ask(dfn[pos]+1,ri[pos]),bit[0].add(dfn[pos],ri[pos],1),bit[1].add(dfn[pos],1);for(int i=0;i<26;++i)if(trie[0].son[v][i])dfs2(trie[0].son[v][i]);for(int i=pre[v].size()-1;i>=0;--i)bit[0].add(dfn[pos],ri[pos],-1),bit[1].add(dfn[pos],-1);
}
void in()
{scanf("%d",&n);for(int i=1,j;i<=n;++i){scanf("%s",ch+1);for(j=1;ch[j]!='#';++j);pre[trie[0].ins(1,j,1)].push_back(i);for(j=strlen(ch+1);ch[j]!='#';--j);suf[i]=trie[1].ins(strlen(ch+1),j,-1);}
}
void ac(){dfs1(0);dfs2(0);printf("%lld",ans);}
int main()
{__asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");__asm__("movl %%eax, %%esp;\n"::"a"(my_stack + sizeof(my_stack) - main_stack):"%esp");in(),ac();
}

[2018.10.20 T3] 巧克力相关推荐

  1. c语言哥德巴赫数学猜想,哥德巴赫数学猜想“1+1”是怎么回事,你知道吗?丨2018/10/20...

    每天写一篇日记,雷打不动 2018年10月20日星期六,上午晴下午阴 [目  录]  何雷西奥日记 今天有点小确幸,在不经意中让我遇见了著名的哥德巴赫猜想. 然后,又让我搞明白了这个数学猜想的基本内容 ...

  2. ROS_Kinetic_01 在 Ubuntu 16.04 安装ROS Kinetic 全教程附资料和镜像 2018.10.20更新

    Exbot易科机器人实验室新站点(测试中):http://server.blackant.org:23452/ 2018 ROS Melodic的迷失与救赎::https://blog.csdn.ne ...

  3. 【联考第一场2018.10.20】

    前言 今天虽然题目难度不大,但是我打爆了. 虽然一开始都想到正解,但后来都没打出来,不敢浪,就先打了个暴力,就第一题直接打的正解. 但是翻车了...第一题只有5分,原因是期望算的最大概率,cmp排序用 ...

  4. ssl提高组周六备考赛【2018.10.20】

    前言 er-竟然卡读入输出还不给快读qwq 成绩 有些dalao被老师拉去USACO了,所以没有 HJW应该去jzoj做题了 RankRankRank PersonPersonPerson Score ...

  5. AI前导课-第一课AI概览(2018/10/20)

    AI概览 一.人工智能技术的过去 1.人工智能发展简史 2.符号主义 (1) • 符号主义(逻辑主义.心理学派.计算机学派) – 原理:物理符号系统假设和有限合理性原理. – 起源:源于数理逻辑. – ...

  6. 【2018.10.20】noip模拟赛Day3 二阶和

    今年BJ省选某题的弱化版-- 这看起来就没那么难了,有几种方法维护,这里提两种. 第一种(傻逼的我写的) 维护 一维&二维前缀和. 对于一个长度为$m$的序列$b_1,b_2,...,b_m$ ...

  7. 2018.10.20 NOIP模拟 蛋糕(线段树+贪心/lis)

    传送门 听说是最长反链衍生出的对偶定理就能秒了. 本蒟蒻直接用线段树模拟维护的. 对于第一维排序. 维护第二维的偏序关系可以借助线段树/树状数组维护逆序对的思想建立权值线段树贪心求解. 代码 转载于: ...

  8. 《惢客创业日记》2018.10.20(周六) 作为主播给喜马拉雅FM的三个建议(上)

    今天,大部分时间都用来处理<惢客创业日记>的音频修改和校验工作,既然想好好做,就尽量不要去投机,还是老老实实的把自己的创业日记写好吧. 另外,今天的工作计划中还有一项任务是对喜马拉雅FM的 ...

  9. 【NOIP2018模拟赛2018.10.20】蒲公英的约定

    题目 题解 –这一看就是数论题...个鬼呀 发现最后要使异或值为0,那lastans必须要等于c 然后又因为lastans^ c=b <=> lastans=b ^ c 所以我们倒着异或, ...

  10. 「COCI 2018.10.20」Teoretičar

    题目链接 如果知道 X X X 可能有一些网络流的做法,但是在此题中网络流也显得不够高效.设最大度数为 D D D,可以构造找到一个 X = 2 ⌈ log ⁡ 2 D ⌉ X=2^{\lceil \ ...

最新文章

  1. Java培训学习步骤有哪些
  2. Worksheet.get_Range Method
  3. 算法与数据结构(排序算法概述)
  4. [Issue Fixed]-Pulse r9.1 embedded browser install failure
  5. 产品策划系列:洞察需求(四)
  6. 7-72 分解质因数 (20 分)
  7. windows下wamp安装
  8. 前端学习(1558):ng-repeat命令
  9. 第八期:继美商务部拉黑多家中国公司后,MIT开始审查对华AI合作项目
  10. 面向对象设计使用语言选择
  11. android 监测bug上传到服务器,基于Android 错误信息捕获发送至服务器的详解
  12. 显示器驱动有什么用_科普一下:电脑显示器用什么接口好,主流接口有哪些?...
  13. Windows8之hyper-v探索
  14. 信息学奥赛一本通(2062:【例1.3】电影票)
  15. 【ECJTU_ACM 11级队员2012年暑假训练赛(8) - F - A Mame】
  16. Echarts数据可视化全解
  17. 在ASP.NET的母版页中使用图片和超链接,HTML标记和ASP.NET标记的不同
  18. Docker网络基础---Docker跨主机容器访问通信
  19. 笔记本WIFI无法上网(无Internet访问权限)
  20. 海南大学计算机网络空间安全学院研究生,海南大学计算机与网络空间安全学院2021考研调剂公告...

热门文章

  1. java 转换成maven项目_java – 将现有项目转换为maven项目
  2. DNS服务双解析邮箱地址
  3. android图片资源加密,手机游戏加密之2d资源加密
  4. linux shell捕获异常,shell脚本中如何获取错误输出
  5. BZOJ1057 [ZJOI2007]棋盘制作 【最大同色矩形】
  6. ORACLE在线切换undo表空间
  7. zabbix 添加jvm监控
  8. Oracle管理监控之如何对数据库进行监控检查
  9. 【转载】ARX程序再VS2002中的调试初探
  10. Java web项目的解耦合