题目大意:n个字符串,支持修改一个位置上的字符串和查询一个区间的子区间中长度乘LCP的最大值,输入字符数和询问数不超过10^5。

做法:求出相邻的LCP长度,区间LCP等于区间最小值,查询分几种情况考虑,一种只有一个串,线段树维护长度最大值即可;若有若干个串,设一个阈值k,若答案的LCP<=k,对于小等k的每一个i,若一个位置的相邻LCP大等i,设为1,否则设为0,即求区间最长连续1,每种i开一棵线段树维护即可;若LCP>k,我们把相邻LCP长度超过k的位置存进set,查询的时候拿出来,直接建笛卡尔树计算答案,由于字符总数有限,这样的位置不会超过L/k个。总时间复杂度为O(nklogn+nL/k),适当调整k,时间复杂度为O(n(nlogn)^0.5)。

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<map>
#include<set>
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
#define MN 100000
#define N 131072
#define K 50
struct node{int l,r,u,mx;}T[K+][N*+];
node operator+(const node&a,const node&b)
{
return (node){a.l+a.u*b.l,b.r+b.u*a.r,a.u*b.u,max(max(a.mx,b.mx),a.r+b.l)};
}
string s[MN+];
int t[N*+],v[MN+],a[MN+],an,Z[MN+],zn,L[MN+],R[MN+],ans,S[MN+];
set<int> st;
void change(int k,int x){for(t[k+=N]=x;k>>=;)t[k]=max(t[k<<],t[k<<|]);}
int query(int l,int r)
{
int res=;
for(l+=N-,r+=N+;l^r^;l>>=,r>>=)
{
if(~l&)res=max(res,t[l+]);
if( r&)res=max(res,t[r-]);
}
return res;
}
void change(node*t,int k,node x){for(t[k+=N]=x;k>>=;)t[k]=t[k<<]+t[k<<|];}
node Query(node*t,int l,int r)
{
node L,R;int ul=,ur=;
for(l+=N-,r+=N+;l^r^;l>>=,r>>=)
{
if(~l&)L=ul?L+t[l+]:(ul=,t[l+]);
if( r&)R=ur?t[r-]+R:(ur=,t[r-]);
}
return ul?ur?L+R:L:R;
}
void renew(int x)
{
cin>>s[x];change(x,s[x].size());
if(v[x]>K)st.erase(x);if(v[x+]>K)st.erase(x+);
for(v[x]=;v[x]<s[x].size()&&v[x]<s[x-].size()&&s[x][v[x]]==s[x-][v[x]];)++v[x];
for(v[x+]=;v[x+]<s[x].size()&&v[x+]<s[x+].size()&&s[x][v[x+]]==s[x+][v[x+]];)++v[x+];
if(v[x]>K)st.insert(x);if(v[x+]>K)st.insert(x+);
node a=(node){,,,},b=(node){,,,};
for(int i=;i<=K;++i)change(T[i],x,v[x]<i?a:b),change(T[i],x+,v[x+]<i?a:b);
}
void dfs(int x)
{
S[x]=;
if(L[x])dfs(L[x]),S[x]+=S[L[x]];
if(R[x])dfs(R[x]),S[x]+=S[R[x]];
ans=max(ans,v[x]*(S[x]+));
}
int p(const set<int>::iterator&i){return i!=st.end()?*i:MN+;}
int main()
{
int n,m,i,l,r,z;
n=read();m=read();
for(i=;i<=n;++i)renew(i);
while(m--)
if(read()==)
{
l=read();r=read();
ans=query(l,r);
if(l<r)for(i=;i<=K;++i)z=Query(T[i],l+,r).mx,ans=max(ans,i*(z?z+:));
set<int>::iterator it=st.upper_bound(l);
for(z=p(it);z<=r;)
{
for(a[an=]=z;(z=p(++it))<=r&&z==a[an]+;)a[++an]=z;
for(i=,zn=;i<=an;++i)
{
L[a[i]]=R[a[i]]=;
while(zn&&v[a[i]]<v[a[Z[zn]]])L[a[i]]=a[Z[zn--]];
R[a[Z[zn]]]=a[i];Z[++zn]=i;
}
dfs(a[Z[]]);
}
printf("%d\n",ans);
}
else renew(read());
}

[Codeforces]862F - Mahmoud and Ehab and the final stage的更多相关文章

  1. Codeforces 959D. Mahmoud and Ehab and another array construction task(构造, 简单数论)

    Codeforces 959D. Mahmoud and Ehab and another array construction task 题意 构造一个任意两个数都互质的序列,使其字典序大等于a序列 ...

  2. Codeforces 862A Mahmoud and Ehab and the MEX

    传送门:CF-862A A. Mahmoud and Ehab and the MEX time limit per test 2 seconds memory limit per test 256 ...

  3. Codeforces 959F Mahmoud and Ehab and yet another xor task 线性基 (看题解)

    Mahmoud and Ehab and yet another xor task 存在的元素的方案数都是一样的, 啊, 我好菜啊. 离线之后用线性基取check存不存在,然后计算答案. #inclu ...

  4. Codeforces 862B - Mahmoud and Ehab and the bipartiteness

    862B - Mahmoud and Ehab and the bipartiteness 思路:先染色,然后找一种颜色dfs遍历每一个点求答案. 代码: #include<bits/stdc+ ...

  5. Codeforces 862C - Mahmoud and Ehab and the xor

    862C - Mahmoud and Ehab and the xor 思路:找两对异或后等于(1<<17-1)的数(相当于加起来等于1<<17-1),两个再异或一下就变成0了 ...

  6. Codeforces 862D. Mahmoud and Ehab and the binary string (二分)

    题目链接:Mahmoud and Ehab and the binary string 题意: 一道交互题,首先给出一个字符串的长度l.现在让你进行提问(最多15次),每次提问提出一个字符串,会返回这 ...

  7. codeforces E. Mahmoud and Ehab and the function(二分+思维)

    题目链接:http://codeforces.com/contest/862/problem/E 题解:水题显然利用前缀和考虑一下然后就是二分b的和与-ans_a最近的数(ans_a表示a的前缀和(奇 ...

  8. codeforces D. Mahmoud and Ehab and the binary string(二分)

    题目链接:http://codeforces.com/contest/862/submission/30696399 题解:这题一看操作数就知道是二分答案了.然后就是怎么个二分法,有两种思路第一种是找 ...

  9. CodeForces 959E Mahmoud and Ehab and the xor-MST (MST+找规律)

    <题目链接> 题目大意: 给定一个数n,代表有一个0~n-1的完全图,该图中所有边的边权为两端点的异或值,求这个图的MST的值. 解题分析: 数据较大,$10^{12}$个点的完全图,然后 ...

随机推荐

  1. SQL函数返回表的示例-Z

    create function [dbo].[GetOperateCustGroup] ( ), ) ) returns @TempTable table (MaxPrice float,MinPri ...

  2. (转)如何在Eclipse中查看JDK类库的源代码

    在Eclipse中查看JDK类库的源代码!!! 设置: 1.点 “window”-> "Preferences" -> "Java" -> & ...

  3. wireshark抓包分析tcp连接与断开

    其实对于网络通信的学习,最好还是能够自己抓到包详细地一下,不然只单单通过文字和图的描述印象不够深刻.本文通过实际的抓包操作来看一下tcp的连接与断开是怎样的. 首先需要去https://www.wir ...

  4. 织梦cms/dedecms清理冗余废弃未引用图片方法

    原理描述: 在原有织梦后台菜单中增加"清理冗余图片按钮",实现清理冗余图片的功能. 操作步骤: 1. 打开后台dede\sys_sql_query.php代码 在该文件中搜索如下代 ...

  5. node框架express

    见识到原生nodeJs服务器的恶心后,我们来用下简单好用的框架吧~ 服务器无非主要提供接口和静态文件读取,直接上代码: const express = require('express'); cons ...

  6. C#-获取字符的GBK编码值

    public static int GetGBKValue(string key) { byte[] gbk = Encoding.GetEncoding("GBK").GetBy ...

  7. Python 黑客相关电子资源和书籍推荐

    原创 2017-06-03 玄魂工作室 玄魂工作室 继续上一次的Python编程入门的资源推荐,本次为大家推荐的是Python网络安全相关的资源和书籍. 在去年的双11送书的时候,其实送过几本Pyth ...

  8. 有货前端 Web-APM 实践

    有货前端 Web-APM 实践 0 背景 有货电商技术架构上采用的是前后端分离,前端是主要以业务展示和接口聚合为主,拥有自己的 BFF (Backend For Frontend),以 nodejs ...

  9. Gitlab的安装及项目新建

    1. Gitlab的安装及仓库创建 1.1下载gitlab安装包 1).官网下载速度较慢 建议先行下载 国内的源里面可以找到最新的版本https://mirrors.tuna.tsinghua.edu ...

  10. JVM学习记录

    本博客是为了自己学习JVM而建立,只记录一些自己学习的经过. 最近在看<深入理解Java虚拟机>这本书,里面的内容,很是乏味,因为看不懂所以就会觉得很枯燥,觉得很枯燥看着看着就犯困,然后就 ...