Jzoj4384 Hashit
2017-12-10 13:15
232 查看
你有一个字符串S,最开始为空,要求支持两种操作
在S后面加入字符c
删除S最后一个字符
每次操作询问S有多少个两两不同子串
应该本来应该用SAM+Trie离线做的,然而为了练一下后缀平衡树就写了
其实也很好写,用哈希比较一下就好了,可以用set实现,开一个数组存每个后缀对应的节点就好
求height也可以用哈希
在S后面加入字符c
删除S最后一个字符
每次操作询问S有多少个两两不同子串
应该本来应该用SAM+Trie离线做的,然而为了练一下后缀平衡树就写了
其实也很好写,用哈希比较一下就好了,可以用set实现,开一个数组存每个后缀对应的节点就好
求height也可以用哈希
#pragma GCC opitmize("O3") #pragma G++ opitmize("O3") #include<set> #include<stdio.h> #include<string.h> #include<algorithm> #define LL long long using namespace std; char s[100010]; int n=0; LL h[100010],bas[100010]={1}; struct suffix{ int x; }; inline LL gH(int l,int r){ return h[r]-h[l-1]*bas[r-l+1]; } inline int lcp(int x,int y){ if(x==y) return 0; int l=-1,r=min(x,y)-1; for(int m;l<r;){ m=l+r+1>>1; if(gH(x-m,x)==gH(y-m,y)) l=m; else r=m-1; } return l+1; } inline bool operator< (suffix a,suffix b){ int c=lcp(a.x,b.x); return s[a.x-c]<s[b.x-c]; } multiset<suffix> w; multiset<suffix>::iterator c[100010],p,q; int main(){ int ans=0; for(int i=1;i<=100000;++i) bas[i]=bas[i-1]*27; for(char o;;){ o=getchar(); if(o=='-'){ p=q=c ; ++p; --q; ans-=n-lcp(p->x,n)-lcp(n,q->x)+(p->x==n || q->x==n?0:lcp(p->x,q->x)); w.erase(c[n--]); } else if(o>='a' && o<='z'){ s[++n]=o; h =h[n-1]*27+o-'a'; p=q=c =w.insert((suffix){n}); ++p; --q; ans+=n-lcp(p->x,n)-lcp(n,q->x)+(p->x==n || q->x==n?0:lcp(p->x,q->x)); } else break; printf("%d\n",ans); } }
相关文章推荐
- [后缀平衡树][JZOJ4384]hashit
- JZOJ 4788. 序列
- jzoj2230 破坏
- 【jzoj4783】【Osu】
- JZOJ 4799 【NOIP2016提高A组模拟9.24】我的快乐时代
- 【JZOJ4809】【NOIP2016提高A组五校联考1】挖金矿
- 【JZOJ4810】道路规划
- JZOJ4813. 【NOIP2016提高A组五校联考2】
- 【JZOJ 4812】string
- NOIP提高组【JZOJ4817】square
- 【JZOJ 4816】【NOIP2016提高组 五校联考4】label
- jzoj4819 算循环
- JZOJ 4820 【NOIP2016提高A组模拟10.15】最大化
- 【JZOJ 1709】【SDOI2008】仪仗队
- JZOJ4823. 小W学物理
- JZOJ 4823 【NOIP2016提高A组集训第1场10.29】小W学物理
- 【jzoj4854】【小澳的坐标系】【动态规划】【矩阵快速幂】
- 【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数
- 【jzoj4870】【涂色游戏】【动态规划】【矩阵快速幂】
- JZOJ 4863 【GDOI2017模拟11.5】Market