【BZOJ1125】【POI2008】poc - splay+哈希

題意:

Description

n列火車,每條有l節車箱。每節車箱有一種顏色(用小寫字母表示)。有m次車箱交換操做。求:對於每列火車,在交換車箱的某個時刻,與其顏色徹底相同的火車最多有多少。

Input

n l m (2 ≤ n ≤ 1000, 1 ≤ l ≤ 100, 0 ≤ m ≤ 100000) n行字符串,長度爲l
node

m行,每行4個數a b c d,a車的第b個字符與c車第d個字符交換。 ios

Output

n個數,在交換車箱的某個時刻,與該車顏色徹底相同的火車最多數目。

題解:

因爲$l$很小,能夠直接哈希判斷兩列火車是否相同;spa

用splay來維護全部火車的哈希值,每次交換操做直接刪除兩個串的哈希值,交換字符從新計算哈希值後再插入便可;code

每次下傳標記的時候把哈希值相同的一段打上標記更新答案;blog

注意當交換的兩個字符在同一個串中時要特殊處理,防止被刪兩次;ip

時間複雜度$O((l+logn)m)$字符串

然而提及來很簡單但我每次寫平衡樹都要調至少1h /微笑get

代碼:

 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 }
相關文章
相關標籤/搜索