BZOJ 1014 Splay+hash

能够支持动态插入的东西很容易想到splay。

然后就是树上的hash了。。

 

悲剧的我没找到哪里错了。。。果断70分wa。。。

 

错误代码(思想是正确的):

View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 
  7 #define N 1000000
  8 
  9 using namespace std;
 10 
 11 char str[N];
 12 int sz[N],son[N][2],fa[N];
 13 int sum,n,root,cnt;
 14 unsigned int hash[N],d[N],val[N];
 15 
 16 inline void pushup(int x)
 17 {
 18     sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;
 19     hash[x]=hash[son[x][0]]+val[x]*d[sz[son[x][0]]]+hash[son[x][1]]*d[sz[son[x][0]]+1];
 20 }
 21 
 22 inline void link(int x,int y,int c)
 23 {
 24     fa[x]=y; son[y][c]=x;
 25 }
 26 
 27 void rotate(int x,int c)
 28 {
 29     int y=fa[x];
 30     link(x,fa[y],son[fa[y]][1]==y);
 31     link(son[x][!c],y,c);
 32     link(y,x,!c);
 33     pushup(y);
 34 }
 35 
 36 void splay(int x,int g)
 37 {
 38     while(fa[x]!=g)
 39     {
 40         int y=fa[x];
 41         int cy=(son[fa[y]][1]==y),cx=(son[y][1]==x);
 42         if(fa[y]==g) rotate(x,cx);
 43         else
 44         {
 45             if(cx==cy) rotate(y,cy);
 46             else rotate(x,cx);
 47             rotate(x,cy);
 48         }    
 49     }
 50     pushup(x);
 51     if(!g) root=x;
 52 }
 53 
 54 inline void newnode(int y,int &x,int sp)
 55 {
 56     x=++cnt; sp++;
 57     fa[x]=y; sz[x]=1; val[x]=sp; hash[x]=sp; 
 58     son[x][0]=son[x][1]=0;
 59 }
 60 
 61 inline void build(int &x,int l,int r,int g)
 62 {
 63     if(l>r) return;
 64     int mid=(l+r)>>1;
 65     newnode(g,x,str[mid]-'a');
 66     build(son[x][0],l,mid-1,x);
 67     build(son[x][1],mid+1,r,x);
 68     pushup(x);
 69 }
 70 
 71 inline void init()
 72 {
 73     scanf("%s",str+1); sum=strlen(str+1);
 74     cnt=0;
 75     newnode(0,root,26);
 76     newnode(root,son[root][1],26);
 77     sz[root]=2;
 78     build(son[son[root][1]][0],1,sum,son[root][1]);
 79     pushup(son[son[root][1]][0]);
 80     pushup(son[root][1]);
 81     pushup(root);
 82 }
 83 
 84 inline int find(int b)
 85 {
 86     int x=root;
 87     while(x)
 88     {
 89         if(sz[son[x][0]]==b) return x;
 90         else if(sz[son[x][0]]>b) x=son[x][0];
 91         else b-=sz[son[x][0]]+1,x=son[x][1];
 92     }
 93 }
 94 
 95 inline int gethash(int x,int y)
 96 {
 97     int fx,fy;
 98     fx=find(x-1); fy=find(y+1);
 99     splay(fx,0); splay(fy,fx);
100     return hash[son[fy][0]];
101 }
102 
103 inline void QUERY(int x,int y)
104 {
105     int l=1,r=sum-y+1,mid,res=0;
106     int hx,hy;
107     while(l<=r)
108     {
109         mid=(l+r)>>1;
110         hx=gethash(x,x+mid-1);
111         hy=gethash(y,y+mid-1);
112         if(hx==hy) res=mid,l=mid+1;
113         else r=mid-1;
114     }
115     printf("%d\n",res);
116 }
117 
118 inline void CHANGE(int x,int sp)
119 {
120     int fx=find(x);
121     splay(fx,0);
122     val[fx]=sp;
123     pushup(fx);
124 }
125 
126 inline void INSERT(int x,int sp)
127 {
128     int fx=find(x),fy=find(x+1);
129     splay(fx,0); splay(fy,fx);
130     newnode(fy,son[fy][0],sp);
131     pushup(son[fy][0]); pushup(fy); pushup(fx);
132 }
133 
134 inline void prep()
135 {
136     d[0]=1;
137     for(int i=1;i<500000;i++)
138         d[i]=d[i-1]*27;
139 }
140 
141 inline void go()
142 {
143     prep();
144     init();
145     scanf("%d",&n);
146     int a,b;
147     while(n--)
148     {
149         scanf("%s",str);
150         if(str[0]=='Q')
151         {
152             scanf("%d%d",&a,&b);
153             if(a>b) swap(a,b); 
154             if(a==b) printf("%d\n",sum-a+1);
155             else QUERY(a,b);
156         }
157         else if(str[0]=='R')
158         {
159             scanf("%d%s",&a,str);
160             CHANGE(a,str[0]-'a');
161         }
162         else
163         {
164             scanf("%d%s",&a,str);
165             INSERT(a,str[0]-'a');
166             sum++; 
167         }
168     }
169 }
170 
171 int main()
172 {
173     go();
174     return 0;
175 }

 

最近状态好差,总要调程序。。

posted @ 2013-01-17 19:58  proverbs  阅读(828)  评论(1编辑  收藏  举报