1. 程式人生 > >【BZOJ1125】【POI2008】poc - splay+雜湊

【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 }