#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/45739895");
}
首先我们发现对于每个串,我们把它hash一下,然后建一棵平衡树来支持“插入”、“删除”、“下传标记”这三种操作就可以记录并更新一个点的答案了。
然后每个串的串长都较小,修改字符时可以暴力重新hash。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 305000
#define P 1050
#define ls son[x][0]
#define rs son[x][1]
#define is(x) (son[fa[x]][1]==x)
#define base 233
#define end(i) (n+(i<<1))
using namespace std;
struct GANK
{
unsigned long long h;
int v,f,k;
void read(unsigned _h,int _v,int _f)
{h=_h,v=_v,f=_f;}
}gank[N];
bool cmph(const GANK &A,const GANK &B){return A.h<B.h;}
bool cmpf(const GANK &A,const GANK &B){return A.f<B.f;}
int ans[N],n,m,p,cnt;
struct SPT
{
int son[N][2],fa[N],root[N],belong[N],num[N],kda[N];
void pushdown(int x)
{
ans[x]=max(ans[x],kda[x]);
kda[ls]=max(kda[ls],kda[x]);
kda[rs]=max(kda[rs],kda[x]);
kda[x]=0;
}
void link(int x,int y,int d){son[y][d]=x,fa[x]=y;}
void rotate(int x)
{
int y,z,i=is(x),t;
y=fa[x],z=fa[y],t=son[x][!i];
pushdown(y),pushdown(x);
link(x,z,is(y)),link(y,x,!i),link(t,y,i);
son[0][0]=son[0][1]=fa[0]=0;
}
void splay(int rt,int x,int d=0)
{
int y,z;
while(fa[x]!=d)
{
y=fa[x],z=fa[y];
if(z==d)rotate(x);
else rotate(is(x)==is(y)?y:x),rotate(x);
}
if(!d)root[rt]=x;
}
int succ(int rt,int x)
{
splay(rt,x);
for(x=rs;ls;x=ls);
return x;
}
void insert(int rt,int v)
{
int x=root[rt];
if(!rs)x=ls;
int suc=succ(rt,x);
splay(rt,suc,x);
pushdown(x),pushdown(suc);
link(v,suc,0),num[rt]++;
splay(rt,v),kda[v]=num[rt],belong[v]=rt;
}
void remove(int rt,int x)
{
splay(rt,succ(rt,x));
splay(rt,x,root[rt]);
pushdown(root[rt]);
pushdown(x);
link(ls,root[rt],0);
ls=rs=fa[x]=0,num[rt]--;
}
void add(int i){insert(gank[i].k,gank[i].v);}
void rem(int i){remove(belong[gank[i].v],gank[i].v);}
void init()
{
int i,j,k;
for(i=1;i<=cnt;i++)
{
int a=end(i)-1,b=end(i);
link(b,root[i]=a,1);
}
for(i=1;i<=n;i++)add(i);
}
}spt;
char s[P][P];
unsigned long long baser;
int main()
{
int i,j,k;
int a,b,c,d;
scanf("%d%d%d",&n,&m,&p);
for(i=1;i<=n;i++)
{
scanf("%s",s[i]+1);
for(baser=0,j=1;j<=m;j++)
baser=baser*base+s[i][j];
gank[i].read(baser,i,0);
}
for(i=1;i<=p;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
if(s[a][b]==s[c][d])
{
i--,p--;
continue;
}
swap(s[a][b],s[c][d]);
for(baser=0,j=1;j<=m;j++)
baser=baser*base+s[a][j];
gank[n+i*2-1].read(baser,a,i);
for(baser=0,j=1;j<=m;j++)
baser=baser*base+s[c][j];
gank[n+i * 2].read(baser,c,i);
}
sort(gank+1,gank+n+p*2+1,cmph);
gank[0].h=gank[1].h^1;
for(i=1;i<n+p*2+1;i++)
{
if(gank[i].h!=gank[i-1].h)cnt++;
gank[i].k=cnt;
}
sort(gank+1,gank+n+p*2+1,cmpf);
spt.init();
for(i=1;i<=p;i++)
{
b=n+i*2,a=b-1;
if(gank[a].v==gank[b].v)
spt.rem(a),spt.add(a);
else {
spt.rem(a),spt.rem(b);
spt.add(a),spt.add(b);
}
}
for(i=1;i<=n;i++)spt.remove(spt.belong[i],i);
for(i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}