这是个后缀平衡树的裸题。。。。

然后傻逼的我调了一下午。

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e5+;
const int bas=;
int hs[N],M[N];
int n,len,ans,Ans[N];
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
struct Suffix_Balanced_ScapeGoat_Tree{
int lx[N],rx[N],rt,size[N],s[N],cnt,Q[N],tail;
ll tag[N];
int get(int i,int l){return hs[i]-hs[i-l]*M[l];}
int qlcp(int x,int y){
int l=,r=min(x,y);
while(l<r){
int mid=(l+r)>>;
if(get(x,mid+)==get(y,mid+))l=mid+;else r=mid;
}
return l;
}
inline bool cmp(int x,int y){int l=qlcp(x,y);return s[x-l]<s[y-l];}
inline int merge(int x,int y){
if(!x||!y)return x|y;
if(size[x]>size[y]){size[x]+=size[y];rx[x]=merge(rx[x],y);return x;}
else{size[y]+=size[x];lx[y]=merge(x,lx[y]);return y;}
}
inline int build(int ls,int rs,ll l,ll r){
if(ls>rs)return ;
int mid=(ls+rs)>>;ll midv=(l+r)>>;int x=Q[mid];tag[x]=midv;
lx[x]=build(ls,mid-,l,midv);rx[x]=build(mid+,rs,midv,r);
size[x]=rs-ls+;return x;
}
inline void dfs(int x){if(lx[x])dfs(lx[x]);Q[++tail]=x;if(rx[x])dfs(rx[x]);}
inline int rebuild(int x,ll l,ll r){
tail=;dfs(x);return build(,tail,l,r);
}
inline int ins(int x,ll l,ll r,int val){
if(!x){
size[++cnt]=;lx[cnt]=rx[cnt]=;tag[cnt]=(l+r)>>;
return cnt;
}
size[x]++;
if(cmp(x,val)){
rx[x]=ins(rx[x],tag[x],r,val);
if(size[rx[x]]>0.65*size[x])x=rebuild(x,l,r);
}
else{
lx[x]=ins(lx[x],l,tag[x],val);
if(size[lx[x]]>0.65*size[x])x=rebuild(x,l,r);
}
return x;
}
inline int del(int x,int val){
if(x==val)return merge(lx[x],rx[x]);
size[x]--;
if(tag[x]<tag[val])rx[x]=del(rx[x],val);
else lx[x]=del(lx[x],val);
return x;
}
inline int queryrk(int key){
int x=rt,ans=;
while(){
int i=size[lx[x]]+;
if(key==x)return ans+i;
if(tag[x]<tag[key])x=rx[x],ans+=i;else x=lx[x];
}
}
inline int find(int key){
int x=rt;
while(){
int i=size[lx[x]]+;
if(key==i)return x;
if(key>i)x=rx[x],key-=i;else x=lx[x];
}
}
inline void del(int x){
int rk=queryrk(x),y=find(rk-),z=find(rk+);
ans-=qlcp(x,y)+qlcp(x,z)-qlcp(y,z);
rt=del(rt,x);cnt--;len--;
}
inline void ins(int x){
s[++len]=x;hs[len]=hs[len-]*bas+x;
rt=ins(rt,,1LL<<,len);
if(len<)return;
int rk=queryrk(len),y=find(rk-),z=find(rk+);
ans+=qlcp(len,y)+qlcp(len,z)-qlcp(y,z);
}
}T;
char str[N];
struct Edge{int u,v,next;}G[N<<];int head[N],tot=;
inline void addedge(int u,int v){
G[++tot].u=u;G[tot].v=v;G[tot].next=head[u];head[u]=tot;
G[++tot].u=v;G[tot].v=u;G[tot].next=head[v];head[v]=tot;
}
inline void dfs(int u,int fa){
T.ins(str[u]-'a'+);Ans[u]=(len-)*(len-)/-ans;
for(int i=head[u];i;i=G[i].next){
if(G[i].v!=fa)dfs(G[i].v,u);
}
T.del(len);
}
int main(){
freopen("balsuffix.in","r",stdin);
freopen("balsuffix.out","w",stdout);
M[]=;
for(int i=;i<N;i++)M[i]=M[i-]*bas;
T.ins();T.ins();int T=read();
while(T--){
n=read();for(int i=;i<=n;i++)head[i]=;tot=;
for(int i=;i<n;i++){
int u=read(),v=read();addedge(u,v);
}
scanf("%s",str+);
dfs(,);
for(int i=;i<=n;i++)printf("%d\n",Ans[i]);
}
}

【COGS2622】后缀平衡树的更多相关文章

  1. 【XSY2773】基因 后缀平衡树 树套树

    题目描述 有一棵树,每条边上面都有一个字母.每个点还有一个特征值\(a_i\). 定义一个节点\(i\)对应的字符串为从这个点到根的路径上所有边按顺序拼接而成的字符串\(s_i\). 有\(m\)次操 ...

  2. 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)

    模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...

  3. 3682: Phorni 后缀平衡树 线段树

    国际惯例的题面: 考虑如果没有强制在线我们能怎么水掉这个题,先构造出字符串,各种方法求一下后缀数组,然后线段树维护区间rank最小的位置即可.然而他要求强制在线,支持插入后缀,并比较后缀大小(求ran ...

  4. BZOJ3682 Phorni 后缀平衡树

    后缀平衡树的裸题 后缀平衡树简单的思想如下 具体的可以去看$clj$的论文 假设我们已经有了串$S$的后缀平衡树 插入一个字母$c$ 我们用$Si$代表原串$S$从第$i$个字符开始的后缀 则后缀$c ...

  5. UOJ#35 后缀排序

    这是一道模板题. 读入一个长度为 n 的由小写英文字母组成的字符串,请把这个字符串的所有非空后缀按字典序从小到大排序,然后按顺序输出后缀的第一个字符在原串中的位置.位置编号为 1 到 n. 除此之外为 ...

  6. 【sam复习】用sam实现后缀排序

    没错,一定是无聊到一定境界的人才能干出这种事情. 这个无聊的zcysky已经不满足于用后缀平衡树求sa了,他想用sam试试. 我们回顾下sam的插入过程,如果我们从最后一个state沿着suffix ...

  7. [BZOJ3600] 没有人的算术 [重量平衡树+权值线段树]

    题面 传送门 思路 这道题目是陈立杰论文<重量平衡树和后缀平衡树在信息学奥赛中的应用 >中关于重量平衡树维护序列排名算法的一个应用 具体方法为:令根节点保存一个实数区间$[0,1]$ 若当 ...

  8. 北京培训记day5

    高级数据结构 一.左偏树&斜堆 orz黄源河论文 合并,插入,删除根节点 打标记 struct Node { int fa,l,r,w,dep } tree[Mx]; int Merge(in ...

  9. [BZOJ 3682]Phorni

    后缀平衡树的模板题? I'm so weak…… 现在觉得替罪羊树比 treap 好写,是不是没救了喵- #include <cstdio> #include <cmath> ...

随机推荐

  1. BZOJ3124 SDOI2013直径

    本以为必有高论,结果是个思博题.随便找一条直径,最后答案肯定是这条直径上的连续一段,如果某分支长度等于直径上某端的长度这一端都要被剪掉. #include<iostream> #inclu ...

  2. [Leetcode] powx n x的n次方

    Implement pow(x, n). 题意:计算x的次方 思路:这题的思路和sqrt的类似,向二分靠近.例如求4^5,我们可以这样求:res=4.4*4^4.就是将每次在res的基础上乘以x本身, ...

  3. Git 常用操作(一)

    使用git pull文件时和本地文件冲突: $ git stash $ git pull $ git stash pop stash@{0}   [还原暂存的内容] 上传项目流程: pwd git p ...

  4. YBT 5.4 状态压缩动态规划

    #loj 10170. 「一本通 5.4 例 1」骑士 看数据范围n<=10,所以不是搜索就是状压dp,又因为搜索会超时所以用dp dp[i][k][j]表示现已经放到第i行,前面共有k个,这一 ...

  5. ExtJs在页面上window再调用Window的事件处理

    今天在开发Ext的过程中遇到了一个恶心的问题,就是在ext.window页面,点击再次弹出window时,gridpanel中的store数据加载异常,不能正常被加载,会出现缓存,出现该问题,是因为w ...

  6. 在Linux中新增与删除用户可以使用命令:Useradd

    在Linux中新增与删除用户可以使用命令:Useradd 我们先使用man命令理解一下Useradd的用法 新增与删除用户操作需要先获取高级用户权限 输入命令:sudo -i 确定后输入高级用户密码 ...

  7. HDU4009:Transfer water(有向图的最小生成树)

    Transfer water Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)To ...

  8. ubuntu10.04 安装gcc4.1.2

    After a bunch of searching to get gcc-4.1 & g++-4.1 in Ubuntu 10.10 (maverick), I found easy wor ...

  9. ACM1258邻接表

    教训:使用邻接表的时候一定要把邻接表的结构组定义的足够大,不能仅仅等于节点的个数,因为线段的数量往往远超过节点的数量. 这个题目是拓扑排序练习,提高下理解. #include<iostream& ...

  10. Leetcode 94. 二叉树的中序遍历

    1.问题描述 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 2.解法一 ...