JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology trie+LCA/哈希
来源:互联网 发布:淘宝卖家关闭佣金 编辑:程序博客网 时间:2024/05/21 04:43
题意:求一些指定串的最长公共后缀,动态加入。
傻逼题,被题意坑了,以为要求最长公共LCS。
hash入门题,二分长度以后判断一下是否所有串都相同。
trie+LCA也可以,不过麻烦一点。
trie+LCA:
#include<cstdio>#include<algorithm>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e5+5;const int M=1e6+5;int ch[M][27],pos[N],dep[M],fa[M][21];int val[N],n,m,sz,a[N];char s[M];inline void ins(int num){ int len=strlen(s+1),x=1; fd(i,len,1) { int c=s[i]-'a'; if (!ch[x][c]) { ch[x][c]=++sz; dep[sz]=dep[x]+1,fa[sz][0]=x; fo(j,1,20)fa[sz][j]=fa[fa[sz][j-1]][j-1]; } x=ch[x][c]; } pos[num]=x;}inline int lca(int x,int y){ if(dep[x]>dep[y])swap(x,y); int j=20; while (dep[x]<dep[y]) { while (j&&dep[fa[y][j]]<dep[x])j--; y=fa[y][j]; } j=20; while(x!=y) { while (j&&fa[x][j]==fa[y][j])j--; x=fa[x][j],y=fa[y][j]; } return x;} int main(){ freopen("biology.in","r",stdin); freopen("biology.out","w",stdout); scanf("%d%d",&n,&m); sz=1; fo(i,1,n) { scanf("%s",s+1); ins(i); } fo(i,1,m) { int op; scanf("%d",&op); if (op==1) { scanf("%s",s+1); ins(++n); } else { int num,k; scanf("%d",&num); fo(j,1,num) { int x; scanf("%d",&x); if (j==1)k=pos[x]; else k=lca(k,pos[x]); } printf("%d\n",dep[k]); } }}
hash(更快更短空间更少):
#include<cstdio>#include<algorithm>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int mo=1e9+7;int n,m;const int N=1e6+5;int hash2[N],now,a[15],p[N],q[N];typedef unsigned long long ull;ull hash1[N];char s[N];inline void ins(int i){ scanf("%s",s); int len=strlen(s); p[i]=now+1,q[i]=now+len; fo(j,1,len) { now++; int tmp=s[len-j]-'a'+1; if (j==1)hash1[now]=hash2[now]=tmp; else { hash1[now]=hash1[now-1]*27+tmp; hash2[now]=(1ll*hash2[now-1]*27%mo+tmp)%mo; } }}inline bool pd(int n,int mid){ int w2=hash2[p[a[1]]+mid-1]; ull w1=hash1[p[a[1]]+mid-1]; fo(i,2,n) if(hash1[p[a[i]]+mid-1]!=w1||hash2[p[a[i]]+mid-1]!=w2)return 0; return 1;}inline int solve(int n){ int l=1,r=now,ans=0; fo(i,1,n)r=min(r,q[a[i]]-p[a[i]]+1); while (l<=r) { int mid=(l+r)>>1; if (pd(n,mid))l=mid+1,ans=mid; else r=mid-1; } return ans;}int main(){ freopen("biology.in","r",stdin); freopen("biology.out","w",stdout); scanf("%d%d",&n,&m); fo(i,1,n)ins(i); while (m--) { int op; scanf("%d",&op); if (op==1)ins(++n); else { int num; scanf("%d",&num); fo(i,1,num)scanf("%d",&a[i]); printf("%d\n",solve(num)); } }}
阅读全文
0 0
- JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology trie+LCA/哈希
- JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology
- 【NOIP2017提高A组模拟10.6】Biology
- NOIP2017提高A组模拟10.6】Biology
- JZOJ 5397. 【NOIP2017提高A组模拟10.6】Biology
- 【JZOJ5397】Biology
- jzoj5363【NOIP2017提高A组模拟9.14】生命之树 trie+启发式合并
- 【NOIP2017提高A组模拟9.14】生命之树 trie+启发式合并
- 【NOIP2017提高A组模拟9.14】生命之树 (dsu on tree+trie)
- [JZOJ5396]【NOIP2017提高A组模拟10.6】Blocks
- 拉格朗日插值法 【NOIP2017提高A组模拟10.6】Count
- JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
- JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
- [JZOJ5395]【NOIP2017提高A组模拟10.6】Count
- JZOJ 5396. 【NOIP2017提高A组模拟10.6】Blocks
- 【JZOJ 5395】【NOIP2017提高A组模拟10.6】Count
- A【NOIP2017提高组模拟12.18】
- 【JZOJ4928】【NOIP2017提高组模拟12.18】A
- 引水入城
- JZOJ1239 邦德(加强版)
- 唉 再瞎搞你就一事无成了
- java基础-多态-接口
- Java并发编程:深入剖析ThreadLocal
- JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology trie+LCA/哈希
- 2017-10-6离线赛总结
- codeforces 862b
- Codeforces Round #438 B. Race Against Time
- 焦点事件
- const的用法,特别是用在函数前面与后面的区别!
- 谈谈对Spring IOC的理解
- 还记得被东方project弹幕支配的恐惧吗
- Windows系列及开源