【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 }
posted @ 2019-01-07 10:16  DCDCBigBig  阅读(281)  评论(0编辑  收藏  举报