JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology trie+LCA/哈希
2017-10-06 15:09
369 查看
题意:求一些指定串的最长公共后缀,动态加入。
傻逼题,被题意坑了,以为要求最长公共LCS。
hash入门题,二分长度以后判断一下是否所有串都相同。
trie+LCA也可以,不过麻烦一点。
trie+LCA:
hash(更快更短空间更少):
傻逼题,被题意坑了,以为要求最长公共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 ,dep[M],fa[M][21]; int val ,n,m,sz,a ; 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 ,now,a[15],p ,q ; typedef unsigned long long ull; ull hash1 ; char s ; 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)); } } }
相关文章推荐
- 拉格朗日插值法 【NOIP2017提高A组模拟10.6】Count
- JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
- JZOJ 5397. 【NOIP2017提高A组模拟10.6】Biology
- [JZOJ5395]【NOIP2017提高A组模拟10.6】Count
- JZOJ 5396. 【NOIP2017提高A组模拟10.6】Blocks
- JZOJ5397. 【NOIP2017提高A组模拟10.6】Biology
- 【JZOJ 5395】【NOIP2017提高A组模拟10.6】Count
- [JZOJ5396]【NOIP2017提高A组模拟10.6】Blocks
- JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
- JZOJ 5401. 【NOIP2017提高A组模拟10.8】Star Way To Heaven
- jzoj. 100031. 【NOIP2017提高A组模拟7.9】外星密码
- JZOJ5401. 【NOIP2017提高A组模拟10.8】Star Way To Heaven
- 【jzoj5286】【NOIP2017提高A组模拟8.16】【花花的森林 】【时间倒流】
- JZOJ 100036 【NOIP2017提高A组模拟7.10】随机
- JZOJ 100046. 【NOIP2017提高A组模拟7.14】收集卡片
- 【JZOJ5287】【NOIP2017提高A组模拟8.16】最短路
- 【jzoj5332】【NOIP2017提高A组模拟8.23】【密码】【ac自动机】【动态规划】
- 【jzoj5335】【NOIP2017提高A组模拟8.24】【早苗】【矩阵乘法快速幂】
- 【JZOJ5335】【NOIP2017提高A组模拟8.24】早苗
- JZOJ5358. 【NOIP2017提高A组模拟9.12】BBQ