【BZOJ1125】【POI2008】poc - splay+哈希
题意:
Description
n列火车,每条有l节车厢。每节车厢有一种颜色(用小写字母表示)。有m次车厢交换操作。求:对于每列火车,在交换车厢的某个时刻,与其颜色完全相同的火车最多有多少。
Input
n l m (2 ≤ n ≤ 1000, 1 ≤ l ≤ 100, 0 ≤ m ≤ 100000) n行字符串,长度为l
m行,每行4个数a b c d,a车的第b个字符与c车第d个字符交换。
Output
n个数,在交换车厢的某个时刻,与该车颜色完全相同的火车最多数目。
题解:
由于$l$很小,可以直接哈希判断两列火车是否相同;
用splay来维护所有火车的哈希值,每次交换操作直接删除两个串的哈希值,交换字符重新计算哈希值后再插入即可;
每次下传标记的时候把哈希值相同的一段打上标记更新答案;
注意当交换的两个字符在同一个串中时要特殊处理,防止被删两次;
时间复杂度$O((l+logn)m)$
然而说起来很简单但我每次写平衡树都要调至少1h /微笑
代码:
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 #define H 173
10 using namespace std;
11 typedef unsigned long long ll;
12 typedef double db;
13 struct node{
14 int son[2],fa,siz;
15 }t[10001];
16 int n,l,m,x,y,a,b,rt,cnt=0,ans[10001],tag[10001];
17 ll pw[101],hs[10001];
18 char s[1001][101];
19 bool Son(int u){
20 return t[t[u].fa].son[1]==u;
21 }
22 void pushup(int u){
23 t[u].siz=t[t[u].son[0]].siz+t[t[u].son[1]].siz+1;
24 }
25 void pd(int u){
26 if(tag[u]){
27 ans[t[u].son[0]]=max(ans[t[u].son[0]],tag[u]);
28 tag[t[u].son[0]]=max(tag[t[u].son[0]],tag[u]);
29 ans[t[u].son[1]]=max(ans[t[u].son[1]],tag[u]);
30 tag[t[u].son[1]]=max(tag[t[u].son[1]],tag[u]);
31 tag[u]=0;
32 }
33 }
34 void rotate(int u){
35 int f=t[u].fa,ff=t[f].fa,ch=Son(u),cf=Son(f);
36 pd(f);
37 pd(u);
38 t[f].son[ch]=t[u].son[ch^1];
39 t[t[f].son[ch]].fa=f;
40 t[ff].son[cf]=u;
41 t[u].son[ch^1]=f;
42 t[u].fa=ff;
43 t[f].fa=u;
44 pushup(f);
45 pushup(u);
46 }
47 void splay(int u,int to){
48 for(;t[u].fa!=to;rotate(u)){
49 int f=t[u].fa;
50 if(t[f].fa!=to)rotate(Son(u)^Son(f)?u:f);
51 }
52 if(!to)rt=u;
53 }
54 int getpre(ll x){
55 int nw=rt,u=rt;
56 for(;nw;){
57 if(x>hs[nw]){
58 u=nw;
59 nw=t[nw].son[1];
60 }else nw=t[nw].son[0];
61 }
62 return u;
63 }
64 int getnxt(ll x){
65 int nw=rt,u;
66 for(;nw;){
67 if(x<hs[nw]){
68 u=nw;
69 nw=t[nw].son[0];
70 }else nw=t[nw].son[1];
71 }
72 return u;
73 }
74 int nxt(int u){
75 int nw=t[u].son[1];
76 while(t[nw].son[0])nw=t[nw].son[0];
77 return nw;
78 }
79 void ins(int x){
80 int u=getpre(hs[x]),v=getnxt(hs[x]);
81 splay(u,0);
82 splay(v,u);
83 t[x].son[0]=t[v].son[0];
84 t[t[x].son[0]].fa=x;
85 t[v].son[0]=x;
86 t[x].fa=v;
87 pushup(x);
88 pushup(v);
89 pushup(u);
90 ans[x]=max(ans[x],t[x].siz);
91 tag[x]=max(tag[x],t[x].siz);
92 }
93 void del(int x){
94 splay(x,0);
95 int u=nxt(x);
96 splay(u,x);
97 rt=u;
98 t[u].son[0]=t[x].son[0];
99 t[t[u].son[0]].fa=u;
100 t[u].fa=0;
101 pushup(u);
102 t[x].son[0]=t[x].son[1]=0;
103 t[x].siz=1;
104 }
105 void dfs(int u){
106 pd(u);
107 if(t[u].son[0])dfs(t[u].son[0]);
108 if(t[u].son[1])dfs(t[u].son[1]);
109 }
110 int main(){
111 scanf("%d%d%d",&n,&l,&m);
112 pw[0]=1;
113 for(int i=1;i<=l;i++)pw[i]=pw[i-1]*H;
114 rt=n+1;
115 t[rt].siz=2;
116 hs[rt]=0;
117 t[rt].son[1]=n+2;
118 t[n+2].siz=1;
119 t[n+2].fa=rt;
120 hs[n+2]=(1ll<<64)-1;
121 for(int i=1;i<=n;i++){
122 scanf("%s",s[i]+1);
123 for(int j=1;j<=l;j++){
124 hs[i]=hs[i]*H+s[i][j];
125 }
126 ins(i);
127 }
128 for(int i=1;i<=m;i++){
129 scanf("%d%d%d%d",&x,&a,&y,&b);
130 if(x==y){
131 del(x);
132 swap(s[x][a],s[x][b]);
133 hs[x]=0;
134 for(int j=1;j<=l;j++){
135 hs[x]=hs[x]*H+s[x][j];
136 }
137 ins(x);
138 }else{
139 del(x);
140 del(y);
141 swap(s[x][a],s[y][b]);
142 hs[x]=hs[y]=0;
143 for(int j=1;j<=l;j++){
144 hs[x]=hs[x]*H+s[x][j];
145 hs[y]=hs[y]*H+s[y][j];
146 }
147 ins(x);
148 ins(y);
149 }
150 }
151 dfs(rt);
152 for(int i=1;i<=n;i++){
153 printf("%d\n",ans[i]);
154 }
155 return 0;
156 }