哈希一下每一个字符串,对每一个哈希值$s$建一棵treap保存(所有哈希值等于$s$的字符串)的下标
每个节点维护一个标记表示这个节点在任何时点,它所处的treap的节点数的最大值(就是答案)
每次修改就暴力重新算哈希值,删除,插入后打一个标记
同一个字符串交换字符要特殊处理
#include<stdio.h>
#include<stdlib.h>
#include<map>
using namespace std;
#define ull unsigned long long
map<ull,int>rt;
map<ull,int>::iterator it;
int fix[1010],l[1010],r[1010],v[1010],p[1010],siz[1010],len;
ull hash_[1010];
char s[1010][110];
struct pr{
int l,r;
pr(int a=0,int b=0){l=a;r=b;}
};
void gao(int x,int d){
v[x]=max(v[x],d);
p[x]=max(p[x],d);
}
void pushdown(int x){
if(p[x]){
if(l[x])gao(l[x],p[x]);
if(r[x])gao(r[x],p[x]);
p[x]=0;
}
}
void pushup(int x){
siz[x]=siz[l[x]]+siz[r[x]]+1;
}
pr split(int x,int k){
if(x==0)return pr();
pushdown(x);
pr s;
if(k<=siz[l[x]]){
s=split(l[x],k);
l[x]=s.r;
s.r=x;
}else{
s=split(r[x],k-siz[l[x]]-1);
r[x]=s.l;
s.l=x;
}
pushup(x);
return s;
}
int merge(int x,int y){
if(x==0)return y;
if(y==0)return x;
if(fix[x]<fix[y]){
pushdown(x);
r[x]=merge(r[x],y);
pushup(x);
return x;
}else{
pushdown(y);
l[y]=merge(x,l[y]);
pushup(y);
return y;
}
}
int lt(int x,int p){
int s=0;
while(x){
if(x<p){
s+=siz[l[x]]+1;
x=r[x];
}else
x=l[x];
}
return s;
}
void gethash(int p){
ull h=0;
for(int i=1;i<=len;i++)h=h*2333ll+(ull)s[p][i];
hash_[p]=h;
}
void dfs(int x){
pushdown(x);
if(l[x])dfs(l[x]);
if(r[x])dfs(r[x]);
}
int main(){
srand(19260817);
int n,m,i,a,b,c,d;
pr s1,s2;
scanf("%d%d%d",&n,&len,&m);
for(i=1;i<=n;i++){
scanf("%s",s[i]+1);
gethash(i);
fix[i]=rand();
siz[i]=v[i]=1;
rt[hash_[i]]=merge(rt[hash_[i]],i);
}
for(it=rt.begin();it!=rt.end();it++)gao(it->second,siz[it->second]);
while(m--){
scanf("%d%d%d%d",&a,&b,&c,&d);
if(a==c){
s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
s2=split(s1.r,1);
rt[hash_[a]]=merge(s1.l,s2.r);
swap(s[a][b],s[a][d]);
gethash(a);
s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
rt[hash_[a]]=merge(s1.l,merge(a,s1.r));
gao(rt[hash_[a]],siz[rt[hash_[a]]]);
}else{
s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
s2=split(s1.r,1);
rt[hash_[a]]=merge(s1.l,s2.r);
s1=split(rt[hash_[c]],lt(rt[hash_[c]],c));
s2=split(s1.r,1);
rt[hash_[c]]=merge(s1.l,s2.r);
swap(s[a][b],s[c][d]);
gethash(a);
s1=split(rt[hash_[a]],lt(rt[hash_[a]],a));
rt[hash_[a]]=merge(s1.l,merge(a,s1.r));
gao(rt[hash_[a]],siz[rt[hash_[a]]]);
gethash(c);
s1=split(rt[hash_[c]],lt(rt[hash_[c]],c));
rt[hash_[c]]=merge(s1.l,merge(c,s1.r));
gao(rt[hash_[c]],siz[rt[hash_[c]]]);
}
}
for(it=rt.begin();it!=rt.end();it++){
if(it->second)dfs(it->second);
}
for(i=1;i<=n;i++)printf("%d\n",v[i]);
}