• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
AC_Artist.zig_zag
然而我依然在补题、
博客园    首页    新随笔    联系   管理    订阅  订阅

bzoj 1014 火星人

比较字符串?不好处理?我们想到用哈希来比较。

每个节点记录它包括它的子树所表示的字符串的哈希值,这样我们可以通过二分长度,旋转出区间来判定。

对于哈希值我们不必取特定的模数,只要让它乘爆就行,int就是模数。

过程想清楚了就很好写了。

prefix
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<cstring>
  6 #define maxn 240000
  7 #define inf 2147483647
  8 #define ms 2147483647
  9 using namespace std;
 10 int c[maxn][2];
 11 int fa[maxn],size[maxn],key[maxn],hx[maxn],po[maxn];
 12 int n,m,num,rot;
 13 
 14 inline void update(int x)
 15 {
 16         if (!x) return ;
 17         hx[x]=(hx[c[x][0]]+(key[x]+hx[c[x][1]]*27)*po[size[c[x][0]]]);
 18         size[x]=size[c[x][0]]+size[c[x][1]]+1;
 19 }
 20 
 21 inline void rotate(int x,int &rot)
 22 {
 23         int y=fa[x],z=fa[y];
 24         int p=(c[y][1]==x),q=p^1;
 25         if (y==rot) rot=x;
 26         else if (c[z][0]==y) c[z][0]=x; else c[z][1]=x;
 27         fa[x]=z; fa[y]=x; fa[c[x][q]]=y;
 28         c[y][p]=c[x][q]; c[x][q]=y;
 29         update(y);
 30 }
 31 
 32 inline void splay(int x,int &rot)
 33 {
 34         while (x!=rot)
 35         {
 36                 int y=fa[x],z=fa[y];
 37                 if (y!=rot)
 38                         if ((c[z][0]==y)xor(c[y][0]==x)) rotate(x,rot); else rotate(y,rot);
 39                 rotate(x,rot);
 40         }
 41         update(x);
 42 }
 43 
 44 inline int build(int l,int r)
 45 {
 46         int mid=(l+r)>>1,left=0,right=0;
 47         if (l<mid) left=build(l,mid-1);
 48         if (r>mid) right=build(mid+1,r);
 49         c[mid][0]=left; c[mid][1]=right;
 50         fa[left]=fa[right]=mid;
 51         update(mid);
 52         return mid;
 53 }
 54 
 55 inline int find(int t,int k)
 56 {
 57         if (k==size[c[t][0]]+1) return t;
 58         if (k<size[c[t][0]]+1) return find(c[t][0],k);
 59         if (k>size[c[t][0]]+1) return find(c[t][1],k-size[c[t][0]]-1);
 60 }
 61 
 62 inline bool judge(int x,int y,int len)
 63 {
 64         if (len==1) return key[find(rot,x+1)]==key[find(rot,y+1)];
 65         int ll=find(rot,x),rr=find(rot,x+len+1);
 66         splay(rr,rot); splay(ll,c[rot][0]);
 67         int a1=hx[c[ll][1]];
 68         
 69         ll=find(rot,y),rr=find(rot,y+len+1);
 70         splay(rr,rot); splay(ll,c[rot][0]);
 71         int a2=hx[c[ll][1]];
 72         return a1==a2;
 73 }
 74 
 75 int main()
 76 {
 77         freopen("prefix.in","r",stdin);
 78         char s[maxn];
 79         scanf("%s",&s);
 80         num=strlen(s);
 81         po[0]=1;
 82         for (int i=1;i<=maxn;i++) po[i]=po[i-1]*27;
 83         key[1]=0;
 84         for (int i=1;i<=num;i++) key[i+1]=s[i-1]-'a'+1;
 85         key[num+2]=0;num+=2;
 86         rot=build(1,num);
 87         //for (int i=1;i<=num;i++) cout<<key[i]<<' ';
 88         //cout<<endl;
 89         //for (int i=1;i<=num;i++) cout<<i<<' '<<fa[i]<<' '<<c[i][0]<<' '<<c[i][1]<<' '<<size[i]<<' '<<key[i]<<' '<<hx[i]<<endl;
 90         scanf("%d\n",&n);
 91         char sign,z;
 92         int x,y;
 93         for (int i=1;i<=n;i++)
 94         {
 95                 scanf("%c",&sign);
 96                 if (sign=='Q')
 97                 {
 98                         scanf("%d %d\n",&x,&y);
 99                         if (x>y) swap(x,y);
100                         int l=1,r=num-1-y,ans=0;
101                         while (l<=r)
102                         {
103                                 int mid=(l+r)>>1;
104                                 if (judge(x,y,mid)) l=mid+1,ans=mid;
105                                 else r=mid-1;
106                         }
107                         printf("%d\n",ans);
108                 }
109                 if (sign=='R')
110                 {
111                         scanf("%d %c\n",&x,&z);
112                         int t=find(rot,x+1);
113                         key[t]=z-'a'+1;
114                         splay(t,rot);
115                 }
116                 if (sign=='I')
117                 {
118                         scanf("%d %c\n",&x,&z);
119                         int ll=find(rot,x+1),rr=find(rot,x+2);
120                         splay(rr,rot); splay(ll,c[rot][0]);
121                         key[++num]=z-'a'+1;
122                         c[ll][1]=num; fa[num]=ll;
123                         splay(num,rot);
124                 }
125         }
126         return 0;
127 }

 

AC without art, no better than WA !
posted @ 2013-03-28 22:46  Zig_zag  阅读(362)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3