bzoj3467
来源:互联网 发布:约瑟夫环java环形链表 编辑:程序博客网 时间:2024/06/06 10:55
题意:
n<=100000
#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<iostream>#include<algorithm>#define N 110000#define maxd 16#define base 233#define lowbit(x) (x&(-x))#define LL long longusing namespace std;struct node{int o,x;}q[N];int sa[N][26],sb[N][26],al,bl,na,nb,wa[N],wb[N],n,par[N][18],h[N][18],cf[18],p[N],dep[N];int L[N],R[N],lt1[N],lt2[N],rk[N],mx;LL ans;inline int read(){ char c=getchar();int t=0; while(c<'0' || c>'9') c=getchar(); while(c>='0' && c<='9') {t=t*10+c-'0';c=getchar();} return t;}void dfs(int x,int fa,int c){ par[x][0]=fa;h[x][0]=c+1; for(int i=1;i<=maxd;i++) par[x][i]=par[par[x][i-1]][i-1],h[x][i]=h[x][i-1]+h[par[x][i-1]][i-1]*cf[i-1]; for(int i=0;i<26;i++) if(sb[x][i]) dfs(sb[x][i],x,i);}bool cmpb(int x,int y){ for(int i=maxd;i>=0;i--) if(h[x][i]==h[y][i]) x=par[x][i],y=par[y][i]; if(h[x][0]<h[y][0]) return 1; return 0;}int kth(int x,int k){ k--; for(int i=maxd;i>=0;i--) if(k&(1<<i)) x=par[x][i]; return h[x][0];}int tdl(int l,int r,int k,int c){ int res=0;c++; while(l<=r) { int mid=(l+r)/2,t=kth(p[mid],k); if(t>=c) {r=mid-1;if(t==c) res=mid;} else l=mid+1; } return res;}int tdr(int l,int r,int k,int c){ int res=0;c++; while(l<=r) { int mid=(l+r)/2,t=kth(p[mid],k); if(t<=c) {l=mid+1;if(t==c) res=mid;} else r=mid-1; } return res;}void dp(int x){ if(R[x]==0) return; for(int i=0;i<26;i++) { int y=sa[x][i]; if(y) { dep[y]=dep[x]+1; L[y]=tdl(L[x],R[x],dep[y],i); R[y]=tdr(L[x],R[x],dep[y],i); dp(y); } }}void change(int *lt,int x,int d){ for(int i=x;i<=mx;i+=lowbit(i)) lt[i]+=d;}int find(int *lt,int x){ int sum=0; for(int i=x;i;i-=lowbit(i)) sum+=lt[i]; return sum;}int main(){ cf[0]=base; for(int i=1;i<=maxd;i++) cf[i]=cf[i-1]*cf[i-1]; scanf("%d",&n); na=nb=al=bl=1;wa[1]=wb[1]=1; for(int i=1;i<=n;i++) { int o=read(),x=read();char c=getchar(); while(c<'a' || c>'z') c=getchar(); q[i].o=o; if(o==1) { x=wa[x];na++; if(sa[x][c-'a']==0) sa[x][c-'a']=++al; wa[na]=sa[x][c-'a']; q[i].x=wa[na]; } else { x=wb[x];nb++; if(sb[x][c-'a']==0) sb[x][c-'a']=++bl; wb[nb]=sb[x][c-'a']; q[i].x=wb[nb]; } } mx=max(al,bl)+1; dfs(1,0,-1); for(int i=1;i<=bl;i++) p[i]=i; sort(p+1,p+bl+1,cmpb); for(int i=1;i<=bl;i++) rk[p[i]]=i; L[1]=1;R[1]=bl; dp(1); ans=1; for(int i=1;i<=n;i++) { int o=q[i].o,x=q[i].x; if(o==1) { if(R[x]) { ans+=find(lt2,R[x])-find(lt2,L[x]-1); change(lt1,L[x],1);change(lt1,R[x]+1,-1); } } else { ans++; ans+=find(lt1,rk[x]); change(lt2,rk[x],1); } printf("%lld\n",ans); } return 0;}
题解:
膜了claris的题解。。
这题有个比较厉害的地方就是字典树预处理向上
先离线建出两棵字典树
将B树的所有点到根的串排序,A树中一个点能匹配的是连续的一段,可以二分处理出每个点匹配的区间。然后用两个树状数组模拟就好。。
0 0
- bzoj3467
- Python基础入门(四)- Print语句
- 四种第三方登录
- NavigationView中headerLayout部分重复显示解决方法
- Mysql MHA 搭建报错:thhere are 2 non-slave servers! MHA manages at most one non-slave server
- 修改安兔兔中8GB存储显示
- bzoj3467
- Redis服务器命令
- 100道动态规划——37 UVA 1218 Perfect Service 树形DP 分析问题
- python学习笔记:2017/4/19---2
- 关于C++异常方面的问题
- java读取properties文件的几种方法
- linux服务器MySQL自动备份(小白轻松掌握)
- 类和对象习题
- solrcloud实现