题面传送门

题意简述:给出 \(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. 初识HTML01

    什么是页面? 页面是基于浏览器的应用程序 页面是数据展示的载体,由浏览器和服务器共同执行产物. 浏览器的功能 向服务器发送用户请求指令 接收并解析数据展示给用户 服务器的功能 存储页面资源 处理并响应 ...

  2. Flink Yarn的2种任务提交方式

    Flink Yarn的2种任务提交方式 Pre-Job模式介绍 每次使用flink run运行任务的时候,Yarn都会重新申请Flink集群资源(JobManager和TaskManager),任务执 ...

  3. Linux搭建SVN服务器详细教程

    前言 本文讲解Linux系统下如何搭建SVN服务器,详细说明各配置项的功能,最终实现可管控多个项目的复杂配置. SVN是subversion的缩写,是一个开放源代码的版本控制系统,通过采用分支管理系统 ...

  4. Jmeter之BeanShell 断言

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15436864.html 博客主页:https://www.cnblogs.com/testero ...

  5. Noip模拟63 2021.9.27(考场惊现无限之环)

    T1 电压机制 把题目转化为找那些边只被奇数环包含. 这样的话直接$dfs$生成一棵树,给每个点附上一个深度,根据其他的非树边都是返祖边 可以算出环内边的数量$dep[x]-dep[y]+1$,然后判 ...

  6. Spring IOC(控制反转)和DI(依赖注入)原理

    一.Spring IoC容器和bean简介 Spring Framework实现了控制反转(IoC)原理,IoC也称为依赖注入(DI). 这是一个过程,通过这个过程,对象定义它们的依赖关系,即它们使用 ...

  7. UVM:6.2.3 sequencer 的grab 操作

    转载:UVM:6.2.3 sequencer 的grab 操作_tingtang13的博客-CSDN博客 1.grab 比lock 优先级更高. 2.lock 是插到sequencer 仲裁队列的后面 ...

  8. Atcoder 题目泛做

    我思维越来越菜了,这样下去感觉要退役了. 听说Atcoder的题练思维?那就试着做一做吧. 坚持每天一两道吧.(很有可能咕掉.) AGC036 官方题解 ---A-Triangle          ...

  9. [WPF] 使用三种方式实现弧形进度条

    1. 需求 前天看到有人问弧形进度条怎么做,我模仿了一下,成果如下图所示: 当时我第一反应是可以用 Microsoft.Toolkit.Uwp.UI.Controls 里的 RadialGauge 实 ...

  10. feign微服务调用携带浏览器信息(header、cookie)

    import feign.RequestInterceptor; import feign.RequestTemplate; import org.apache.commons.collections ...