题面传送门

题意简述:给出 \(n\) 个字符串 \(s_i\),每个 \(s_i\) 初始权值为 \(0\)。\(q\) 次操作:修改 \(s_i\) 的权值;查询给出字符串 \(q\) 能匹配的所有 \(s_i\) 的最大权值。


看到 “字符串匹配” 就应该想到 ACAM 了吧。根据 ACAM 的性质,所有后缀能匹配 \(s_i\) 的字符串都应该在 fail 树上以 \(end_i\) 为根的子树里(\(end_i\) 是 \(s_i\) 的结束位置)。那么对于 \(s_i\),将 \([dfn_{end_i},dfn_{end_i}+sz_{end_i}-1]\) 的所有位置都加入其权值,那么如果每个位置用 multiset 维护权值,再用线段树辅助修改(修改的时候直接跑到线段树上 \([l,r]\) 所分解成的所有区间,将原来的值从该点的 multiset 里面删除,再插入新的权值)和查询(将 \(q\) 跑到的每一个位置查询该位置上 multiset 的最大值,即在线段树上从根跑到该叶子节点所经过的所有区间的 multiset 最大值),就可以做到 \(\log^2\) 修改 \(\log\) 查询。实际上就是线段树套平衡树(set)。

时间复杂度 \(\mathcal{O}((m+n)\log^2 n)\)。

不用快读:TLE(2s+);用了快读:700ms。

/*
Powered by C++11.
Author : Alex_Wei.
*/ #pragma GCC optimize(3) #include <bits/stdc++.h>
using namespace std; namespace IO{
char buf[1<<21],*p1=buf,*p2=buf,obuf[1<<23],*O=obuf;
#ifdef __WIN32
#define gc getchar()
#else
#define gc (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
#endif
#define pc(x) (*O++=x)
#define flush() fwrite(obuf,O-obuf,1,stdout) inline int read(){
int x=0,sign=0; char s=gc;
while(!isdigit(s))sign|=s=='-',s=gc;
while(isdigit(s))x=(x<<1)+(x<<3)+(s-'0'),s=gc;
return sign?-x:x;
}
inline string reads(){
string t; char s=gc;
while(!isalpha(s))s=gc;
while(isalpha(s))t+=s,s=gc;
return t;
}
inline void print(int x){
if(x<0)return pc('-'),print(-x),void();
if(x>9)print(x/10);
pc(x%10+'0');
}
} using namespace IO; const int N=3e5+5;
const int S=26; int cnt,v[N],f[N],son[N][S],ed[N];
int dn,dfn[N],sz[N];
vector <int> e[N];
void ins(string s,int id){
int p=0;
for(char it:s){
if(!son[p][it-'a'])son[p][it-'a']=++cnt;
p=son[p][it-'a'];
} ed[id]=p;
} void build(){
queue <int> q;
for(int i=0;i<26;i++)if(son[0][i])q.push(son[0][i]);
while(!q.empty()){
int t=q.front(); q.pop();
for(int i=0;i<26;i++)
if(son[t][i])f[son[t][i]]=son[f[t]][i],q.push(son[t][i]);
else son[t][i]=son[f[t]][i];
e[f[t]].emplace_back(t);
}
} void dfs(int id){
dfn[id]=++dn,sz[id]=1;
for(int it:e[id])dfs(it),sz[id]+=sz[it];
} multiset <int> val[N<<2];
void modify(int l,int r,int ql,int qr,int ori,int nw,int x){
if(ql<=l&&r<=qr){
auto it=val[x].find(ori);
if(it!=val[x].end())val[x].erase(it);
val[x].insert(nw);
return;
} int m=l+r>>1;
if(ql<=m)modify(l,m,ql,qr,ori,nw,x<<1);
if(m<qr)modify(m+1,r,ql,qr,ori,nw,x<<1|1);
} int query(int l,int r,int p,int x){
int ans=val[x].size()?*--val[x].end():-1;
if(l==r)return ans;
int m=l+r>>1;
if(p<=m)ans=max(ans,query(l,m,p,x<<1));
else ans=max(ans,query(m+1,r,p,x<<1|1));
return ans;
} int n,q;
string s;
int main(){
cin>>n>>q;
for(int i=1;i<=n;i++)ins(reads(),i);
build(),dfs(0);
for(int i=1;i<=n;i++)modify(1,dn,dfn[ed[i]],dfn[ed[i]]+sz[ed[i]]-1,0,0,1);
for(int i=1;i<=q;i++){
int t=read();
if(t==1){
int p=read(),x=read();
modify(1,dn,dfn[ed[p]],dfn[ed[p]]+sz[ed[p]]-1,v[p],x,1),v[p]=x;
} else{
int p=0,ans=-1; s=reads();
for(char it:s){
p=son[p][it-'a'];
ans=max(ans,query(1,dn,dfn[p],1));
} print(ans),pc('\n');
}
}
return flush(),0;
}

CF1437G Death DBMS的更多相关文章

  1. 题解 CF1437G Death DBMS

    这题感觉不是很难,但是既然放在 \(\texttt{EDU}\) 的 \(\texttt{G}\) 题,那么还是写写题解吧. \(\texttt{Solution}\) 首先看到 "子串&q ...

  2. ACAM 题乱做

    之前做了不少 ACAM,不过没怎么整理起来,还是有点可惜的. 打 * 的是推荐一做的题目. I. *CF1437G Death DBMS 见 我的题解. II. *CF1202E You Are Gi ...

  3. Educational Codeforces Round 97 (Rated for Div. 2)

    补了一场Edu round. A : Marketing Scheme 水题 #include <cstdio> #include <algorithm> typedef lo ...

  4. 【清北学堂】 死亡(death)

    M个位置可以打sif,N+1个人等着打sif,已知前N个人的时间,问第N+1个人什么时候才能打sif(不能插队,即必须按顺序来打sif) 输入N,M以及每个人所需要的时间:输出第N+1个人所需的时间 ...

  5. HDU 5860 Death Sequence(死亡序列)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  6. Ping of Death

    [Ping of Death] The ping of death attack, or PoD, can cripple a network based on a flaw in the TCP/I ...

  7. Teamcenter 2007 "由于某些意外的 DBMS 错误失败"

    PLM系统实施过程中经常需要做整个系统的克隆备份.Teamcenter2007在做基于Oracel的系统克隆时,用exp功能导出数据表,部署在目标机器上时会遇到DBMS错误,导致后续DB写操作无法进行 ...

  8. 2016暑假多校联合---Death Sequence(递推、前向星)

    原题链接 Problem Description You may heard of the Joseph Problem, the story comes from a Jewish historia ...

  9. 2015年第5本(英文第4本):Death on the Nile尼罗河上的惨案

    书名:Death on the Nile 作者: Agatha Christie 单词数:7.9万(读完后发现网上还有一个版本,总共2.7万单词,孩子都能读懂,看来是简写版) 词汇量:6700 首万词 ...

随机推荐

  1. Noip模拟35 2021.8.10

    考试题目变成四道了,貌似确实根本改不完... 不过给了两个小时颓废时间确实很爽(芜湖--) 但是前几天三道题改着不是很费劲的时候为什么不给放松时间, 非要在改不完题的时候颓?? 算了算了不碎碎念了.. ...

  2. 零基础入门stm32基本定时器详解

    一.基本定时器介绍 在STM32中,基本定时器有TIM6.TIM7等.基本定时器主要包含时基单元,提供16位的计数,能计数0~65535.基本定时器除了计数功能以外,还能输出给DAC模块一个TRGO信 ...

  3. Python | 实现pdf文件分页

    不知道大家有没有遇到过这么一种情况,就比如一个pdf格式的电子书,我们经常浏览的是其中的一部分,而这电子书的页数很大,每当需要浏览时,就需要翻到对应的页码,就有点儿繁琐. 还有一些情况,比如,我们想分 ...

  4. P2472 [SCOI2007]蜥蜴(最大流)

    P2472 [SCOI2007]蜥蜴 自己第一道独立做题且一遍AC的网络流题纪念... 看到这道题我就想到网络流建图的方式了... 首先根据每个高度,我们将每个点拆成两个点限流.之后根据跳的最大距离, ...

  5. HTML基础强化

    1.如何理解HTML? HTML类似于一份word"文档" 描述文档的"结构" 有区块和大纲 2.对WEB标准的理解? Web标准是由一系列标准组合而成.一个网 ...

  6. element-UI 中的upload组件如何添加token?

    <el-upload :show-file-list="false" :on-error="errmsg" :headers="headers& ...

  7. 『学了就忘』Linux基础命令 — 22、Linux中的硬链接和软链接

    目录 1.文件和目录的基本存储 2.In命令介绍 (1)我们来看看ln命令的基本信息 (2)ln命令的基本格式 3.创建硬链接 (1)如何创建硬链接 (2)硬链接特征 (3)硬连接原理 4.创建软链接 ...

  8. httprunner3源码解读(2)models.py

    源码目录结构 我们首先来看下models.py的代码结构 我们可以看到这个模块中定义了12个属性和22个模型类,我们依次来看 属性源码分析 import os from enum import Enu ...

  9. VSCode PHP 开发环境配置 详细教程

    VSCode PHP 开发环境配置 详细教程 这篇文章主要介绍了VScode+PHPstudy配置PHP开发环境的步骤,整理了官方以及优秀第三方的内容,对于学习和工作有一定借鉴意义. 配置过程 第一步 ...

  10. Cannot find ./catalina.sh The file is absent or does not have execute permission This file is needed to run this program(问题解决)

    web项目没有打成包,直接放在了linux服务器上. 进入tomcat/bin目录,执行启动的时候出现如下错误: 解决方法: 在tomcat 的bin目录下 执行这条命令chmod +x *.sh   ...