哈希一下每一个字符串,对每一个哈希值$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]); }