CF1437G Death DBMS
题意简述:给出 \(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的更多相关文章
- 题解 CF1437G Death DBMS
这题感觉不是很难,但是既然放在 \(\texttt{EDU}\) 的 \(\texttt{G}\) 题,那么还是写写题解吧. \(\texttt{Solution}\) 首先看到 "子串&q ...
- ACAM 题乱做
之前做了不少 ACAM,不过没怎么整理起来,还是有点可惜的. 打 * 的是推荐一做的题目. I. *CF1437G Death DBMS 见 我的题解. II. *CF1202E You Are Gi ...
- Educational Codeforces Round 97 (Rated for Div. 2)
补了一场Edu round. A : Marketing Scheme 水题 #include <cstdio> #include <algorithm> typedef lo ...
- 【清北学堂】 死亡(death)
M个位置可以打sif,N+1个人等着打sif,已知前N个人的时间,问第N+1个人什么时候才能打sif(不能插队,即必须按顺序来打sif) 输入N,M以及每个人所需要的时间:输出第N+1个人所需的时间 ...
- HDU 5860 Death Sequence(死亡序列)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...
- 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 ...
- Teamcenter 2007 "由于某些意外的 DBMS 错误失败"
PLM系统实施过程中经常需要做整个系统的克隆备份.Teamcenter2007在做基于Oracel的系统克隆时,用exp功能导出数据表,部署在目标机器上时会遇到DBMS错误,导致后续DB写操作无法进行 ...
- 2016暑假多校联合---Death Sequence(递推、前向星)
原题链接 Problem Description You may heard of the Joseph Problem, the story comes from a Jewish historia ...
- 2015年第5本(英文第4本):Death on the Nile尼罗河上的惨案
书名:Death on the Nile 作者: Agatha Christie 单词数:7.9万(读完后发现网上还有一个版本,总共2.7万单词,孩子都能读懂,看来是简写版) 词汇量:6700 首万词 ...
随机推荐
- 【UE4 C++】Actor 与 Component —— 创建、销毁
Actor的生成与销毁 创建Actor实例 UClass* TSubclassOf<T> SpawnActor() UPROPERTY(EditAnywhere, Category = & ...
- vue3.x异步组件
在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块 vue2.x 曾经简单的异步组件 components: { AsyncComponent: () =& ...
- python png图片生成gif
有时候写代码就是这样别人把代码写好你在后面加一个句号就行了 我很懒不想写成函数,你自己来吧.有注释就不错了 这个依赖一个图像处理库pillow,轮子就是轮他不是车 import imageio imp ...
- LiveVideoStackCon2021 北京站专访:从上云到创新,视频云的新技术、新场景
伴随着视频技术的进步和标准的迭代,视频产业从模拟进入到数字时代,完成了从电影电视到互联网的媒介转换,并且衍生出了超高清.3D.AR/VR 等多种创新形态.特别是在后疫情的当下,我们可以看到音视频技术领 ...
- [对对子队]会议记录5.27(Scrum Meeting12)
今天已完成的工作 朱俊豪 工作内容:寻找电池模型和BGM,修改关卡选择场景 相关issue:优化初步导出版本 相关签入:perf:地图界面优化 feat:更新系列资源(星星,大电池) 何瑞 ...
- RocketMQ源码详解 | Producer篇 · 其二:消息组成、发送链路
概述 在上一节 RocketMQ源码详解 | Producer篇 · 其一:Start,然后 Send 一条消息 中,我们了解了 Producer 在发送消息的流程.这次我们再来具体下看消息的构成与其 ...
- 单片机stm32的5个时钟源的详细分析
众所周知STM32有5个时钟源HSI.HSE.LSI.LSE.PLL,其实他只有四个,因为从上图中可以看到PLL都是由HSI或HSE提供的. 其中,高速时钟(HSE和HSI)提供给芯片主体的主时钟.低 ...
- Python基础——数据类型——字符串
整数.浮点数.布尔值的用法大同小异,而Python字符串的一些用法不易记住,这里以廖雪峰教程为基础,进行一些思考和复习总结. 字符串是什么? 以单引号'或者双引号"括起来的任意文本,比如:& ...
- 查找最小生成树:克鲁斯克尔算法(Kruskal)算法
一.算法介绍 Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表.用来解决同样问题的还有Prim算法和Boruvka算法等.三种算法都是贪心算法的应用.和 ...
- Shadertoy 教程 Part 2 - 圆和动画
Note: This series blog was translated from Nathan Vaughn's Shaders Language Tutorial and has been au ...