就一篇题解:

BZOJ3467 : Crash和陶陶的游戏 - weixin_34248487的博客 - CSDN博客

1.离线,建出Atrie树;B树的倍增哈希数组,节点按照到根路径字典序排序

2.处理A节点对应前缀对应B中的极长可以匹配的区间。在父亲节点区间内二分即可

3.更新答案:

①加入A点,找区间中B中已经出现点个数。树状数组

②加入B点,本质是B到根的字符串放在trie最大匹配长度,二分,哈希表存A树是否有这个前缀,得到的长度就是当前匹配长度。

直上直下的链本质是字符串的前缀后缀。

动态更新hash很难,就离线,在可能贡献的集合内找到当前出现的。

假装有代码.jpg

这个是两个logn的

可以变成一个logn!

sort是不必要的,

对于②B树点对trie的影响,不妨直接倍增+hash找到最长的匹配位置y,在y的位置++,然后①时候子树查询即可!

通过提前打好标记使得不用同时考虑很多!

(类似预处理)

还有可能一个点有多个c儿子,要合并成一个。①的时候整个子树++,表示到根的路径上多了一个点,②的时候,匹配最长位置单点查询这个值

两个树状数组

注意,unsigned long long哈希

单模数随便rand就卡掉了

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define ul unsigned long long
#define ll unsigned long long
using namespace std;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');} namespace Miracle{
const int N=2e5+;
const ul base=;
const int orz=; struct HA{
int nxt[N],hd[N],cnt;
ul val[N];
int id[N];
void ins(int x,ll h){
int pos=h%orz;
nxt[++cnt]=hd[pos];hd[pos]=cnt;val[cnt]=h;
id[cnt]=x;
}
int query(ll h){
int pos=h%orz;
for(reg i=hd[pos];i;i=nxt[i]){
if(val[i]==h) return id[i];
}
return -;
}
}ha;
//trie
int ch[N][];
int id[N];//is
int n;
int tot;
int lp;
ul pw[(<<)+];
void ins(int x,int c){
++lp;
x=id[x];
// cout<<" true fa "<<x<<" ch "<<ch[x][c]<<endl;
if(ch[x][c]){
id[lp]=ch[x][c];return;
}
id[lp]=++tot;
ch[x][c]=tot;
}
int dfn[N],df,dfn2[N];
void fin(int x,ul haxi,int d){
dfn[x]=++df;
if(x!=){
ha.ins(x,haxi);
}
for(reg i=;i<;++i){
if(ch[x][i]){
fin(ch[x][i],haxi+(ll)pw[d]*(i+),d+);
}
}
dfn2[x]=df;
}
//B tree
int cur;
struct node{
int nxt,to;
int val;
}e[*N];
int hd[N],cnt;
void add(int x,int y,int z){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
e[cnt].val=z;
hd[x]=cnt;
}
int fa[N][];
ul hsh[N][];
void dfs(int x){
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
fa[y][]=x;
hsh[y][]=e[i].val+;
dfs(y);
}
}
//question
struct que{
int typ,fa,c;
int x;
}q[N]; int get(int x){
ll now=;
int has=;
int ret=;
for(reg j=;j>=;--j){
if(!fa[x][j]) continue;
ll tmp=((ll)now+pw[has]*hsh[x][j]);
int nc=ha.query(tmp);
if(nc!=-){
ret=nc;
now=tmp;
has+=(<<j);
x=fa[x][j];//shit
}
}
return ret;
} struct treearray{
int f[N];
int n;
void upda(int x,int c){
for(;x<=n;x+=x&(-x)) f[x]+=c;
}
int query(int x){
int ret=;
for(;x;x-=x&(-x)) ret+=f[x];return ret;
}
}t1,t2;
int main(){
rd(n);
char s[];
++tot;++cur;//start
lp=;
id[]=; ll ans=;
ans=;//1 1
for(reg i=;i<=n;++i){
rd(q[i].typ);rd(q[i].fa);//rd(q[i].c);
scanf("%s",s+);q[i].c=s[]-'a';
if(q[i].typ==){
ins(q[i].fa,q[i].c);
q[i].x=id[lp];
// prt(id,1,lp);
}else{
++cur;
q[i].x=cur;
add(q[i].fa,cur,q[i].c);
}
// cout<<tot<<" ";
}
// cout<<endl<<endl;
dfs();
// cout<<"after dfs "<<tot<<endl;
// prt(id,1,lp); pw[]=;
for(reg i=;i<=(<<);++i){
pw[i]=(ll)pw[i-]*base;//%mod;
}
for(reg j=;j<=;++j){
for(reg i=;i<=cur;++i){
fa[i][j]=fa[fa[i][j-]][j-];
hsh[i][j]=((ll)hsh[i][j-]+(ll)hsh[fa[i][j-]][j-]*pw[<<(j-)]);//%mod)%mod;
}
}
// cout<<"after bezeng "<<endl;
fin(,,);
// cout<<" after fin "<<endl;
t1.n=t2.n=tot;
// cout<<" tot "<<tot<<endl;
// prt(dfn,1,tot);
// cout<<" dfn2-------------------------- "<<endl;
// prt(dfn2,1,tot);
int tc=,tb=;
for(reg i=;i<=n;++i){
if(q[i].typ==){//add trie
++tc;
// cout<<"trie "<<endl;
int x=q[i].x;//ch[id[q[i].fa]][q[i].c];
// cout<<"x "<<x<<" tc "<<tc<<endl;
ans+=t1.query(dfn2[x])-t1.query(dfn[x]-);
t2.upda(dfn[x],);t2.upda(dfn2[x]+,-);
}else{//add B tree
++tb;
// cout<<" Btree "<<endl;
// cout<<" x "<<q[i].x<<endl;
int y=get(q[i].x);
// cout<<" y "<<y<<" tb "<<tb<<" dfn "<<dfn[y]<<endl;
if(y){
ans+=t2.query(dfn[y]);
t1.upda(dfn[y],);
}
++ans;
}
printf("%lld\n",ans);
}
return ;
} }
signed main(){
// freopen("5.in","r",stdin);
// freopen("my.out","w",stdout);
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2019/3/26 18:56:24
*/

bzoj3467: Crash和陶陶的游戏的更多相关文章

  1. P1676陶陶吃苹果 - vijos

    描述 curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果, ...

  2. bzoj 2402: 陶陶的难题II 二分答案维护凸包

    2402: 陶陶的难题II Time Limit: 40 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 68  Solved: 45[Submi ...

  3. bzoj 2401: 陶陶的难题I 数论

    2401: 陶陶的难题I Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 89  Solved: 24[Submit][Status] Descript ...

  4. 武汉科技大学ACM:1007: 陶陶摘苹果

    Problem Description 厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的最大高度,请帮陶陶算一下她能够摘到的苹 ...

  5. 洛谷-陶陶摘苹果(升级版)-BOSS战-入门综合练习1

    题目描述 Description 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他手够不着时,他会站到椅子上再试试. 这次与NOIp2005普及组第一题不同 ...

  6. NOIP2005-普及组复赛-第一题-陶陶摘苹果

    题目描述 Description 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳 ...

  7. noip普及组2005 陶陶摘苹果

    陶陶摘苹果 描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 现在 ...

  8. 2719:陶陶摘苹果-poj

    2719:陶陶摘苹果 总时间限制:  1000ms 内存限制:  65536kB 描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出10个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个30厘米 ...

  9. [Vijos 1676] 陶陶吃苹果

    Description curimit知道陶陶很喜欢吃苹果.于是curimit准备在陶陶生日的时候送给他一棵苹果树. curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上 ...

随机推荐

  1. Day1 基础知识

    数据类型,字符编码 二进制: 定义:二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是“逢二进一”,借位规则是“借一当二”.当前的计算机系统使用的基本上是二进制系统,数据在计算机中主要是 ...

  2. 思维导图,UML图,程序流程图制作从入门到精通

    工具: https://www.processon.com/ 第一 用例图 第二 时序图 第三 流程图

  3. 一、使用Navicat连接阿里云服务器宝塔面板里创建的数据库

    一.数据库配置连接  (通过新增用户的方式)

  4. xml-dtd

    dtd用于校验XML的语法. dtd步骤: 1.看XML中有多少个元素,有几个元素,在dtd文件中写几个<!ELEMENT> 2.判断元素是简单元素还是复杂元素 -复杂元素:有子元素的元素 ...

  5. js中对URL进行转码与解码

    1. escape 和 unescape escape()不能直接用于URL编码,它的真正作用是返回一个字符的Unicode编码值. 采用unicode字符集对指定的字符串除0-255以外进行编码.所 ...

  6. 使用js主函数的原因是等文档加载完了才给里面的元素添加东西 如果不使用主函数则文档加载时候无法找到元素则不能成功给元素添加事件

    使用js主函数的原因是等文档加载完了才给里面的元素添加东西 如果不使用主函数则文档加载时候无法找到元素则不能成功给元素添加事件

  7. c++ 的绝对值函数

    添加头文件 #include <cmath> 对于整数 abs(); 对于浮点数 fabs();

  8. Js 中一系列宽度和高度的学习

    在学习元素一系列宽度和高度之前,我们先来看一个平时开发中几乎不会遇到的问题,那就是html文档声明<!DOCTYPE html> 确实会对元素的宽高产生影响.几乎不会遇到,是因为我们在写h ...

  9. codeforces569B

    Inventory CodeForces - 569B Companies always have a lot of equipment, furniture and other things. Al ...

  10. linux系统命令大全

    文件管理 cat chattr chgrp chmod chown cksum cmp cp cut diff diffstat file find git gitview in indent les ...