题目大意: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. beta冲刺2

    q前言:今天晚上大概把github的的相关东西弄上了.然后把之前做的一些修改什么的也上传上去了.目测之后的话就是在自己这边改完然后直接上github那边去复制粘贴替换掉了. 昨天的问题:github这 ...

  2. C语言第三次作业--嵌套循环

    一.PTA实验作业 题目1:硬币数 1. 本题PTA提交列表 2. 设计思路 步骤一:定义整型变量fen5,fen2,fen1,表示1分2分和5分,零钱数额x,总硬币数total,换法count 步骤 ...

  3. IIS 错误代码

    错误码: 1.HTTP 1xx-信息提示 这些状态代码表示临时的响应.客户端在收到常规响应之前,应准备接收一个或多个1xx响应. 100-继续. 101-切换协议. 2xx-成功 这类状态代码表明服务 ...

  4. python 实现cm批量上传

    import requests import json import time import random url = 'http://cm.admin.xxxx.com/customer/aj_ad ...

  5. iOS开发之Objective-C与JavaScript的交互

    UIWebView是iOS最常用的SDK之一,它有一个stringByEvaluatingJavaScriptFromString方法可以将javascript嵌入页面中,通过这个方法我们可以在iOS ...

  6. slf4j 与 log4j2 实战讲解与日志分割

    这两天搭建项目的时候用到log4j2在这里把自己的问题与了解拿出来与大家分享一下. 1.为什我要用 因为,使用slf4j可以很好的保证我们的日志系统具有良好的兼容性,兼容当前常见几种日志系统,而使用l ...

  7. $.each遍历json数组

    1.遍历单层json数组 我们把idx和obj都打印出来看看,到底是什么东西 var json1 =[{"id":"1","tagName" ...

  8. Java可重入锁如何避免死锁

    本文由https://bbs.csdn.net/topics/390939500和https://zhidao.baidu.com/question/1946051090515119908.html启 ...

  9. JAVA_SE基础——29.构造函数

    黑马程序员入学Blog... jvm创建Java对象时候需要调用构造器,默认是不带参数的.在构造器中,你可以让jvm帮你初始化一些参数或者执行一系列的动作. 它是对象创建中执行的函数,及第一个被执行的 ...

  10. JavaScript正则表达式学习笔记(二) - 打怪升级

    本文接上篇,基础部分相对薄弱的同学请移步<JavaScript正则表达式学习笔记(一) - 理论基础>.上文介绍了8种JavaScript正则表达式的属性,本文还会追加介绍几种JavaSc ...