[JSOI2015][JZOJ4061]字符串树
来源:互联网 发布:mysql 字段原子累加 编辑:程序博客网 时间:2024/05/01 18:34
题目大意
一棵有
题目分析
唉,太水了太水了。
对整棵树建可持续化字典树,每个节点上树的副本是以其父亲节点为根的字典树。
查询时用两个点都直接走一遍,再用最近公共祖先的两边去减掉重复的即可。
时间复杂度
具体细节详见代码实现。
代码实现
#include <iostream>#include <cstring>#include <cstdio>#include <cctype>#include <cmath>using namespace std;int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) { if (ch=='-') f=-1; ch=getchar(); } while (isdigit(ch)) { x=x*10+ch-'0'; ch=getchar(); } return x*f;}const int N=100005;const int M=(N-1)<<1;const int E=N<<1;const int LGE=17;const int L=10;const int S=N*L+N;struct TRIE{ int tov[S][26],size[S]; int root[N+1]; int tot; int newnode() { ++tot; for (int i=0;i<26;i++) tov[tot][i]=0; size[tot]=0; return tot; } int insert(char str[],int rt0) { int len=strlen(str); int rt=newnode(),ret=rt; for (int c=0;c<26;c++) tov[rt][c]=tov[rt0][c]; size[rt]=size[rt0]+1; for (int i=0;i<len;i++) { tov[rt][str[i]-'a']=newnode(); rt=tov[rt][str[i]-'a']; rt0=tov[rt0][str[i]-'a']; for (int c=0;c<26;c++) tov[rt][c]=tov[rt0][c]; size[rt]=size[rt0]+1; } return ret; } int query(char str[],int rt) { int len=strlen(str); for (int i=0;i<len;i++) rt=tov[rt][str[i]-'a']; return size[rt]; }}trie;struct TREE{ int last[N+1],tov[M+1],next[M+1],pos[N+1],high[N+1],fa[N+1],root[N+1]; int rmq[E+1][LGE+1]; char st[M+1][L+5]; int euler[E+1]; int tot,e,lge; void insert(int x,int y,char s[L+5]) { tov[++tot]=y; strcpy(st[tot],s); next[tot]=last[x]; last[x]=tot; } void calc(int x) { int i=last[x],y; euler[++e]=x; pos[x]=e; while (i) { y=tov[i]; if (y!=fa[x]) { fa[y]=x; high[y]=high[x]+1; root[y]=trie.insert(st[i],root[x]); calc(y); euler[++e]=x; } i=next[i]; } } void build() { lge=(int)trunc(log(e)/log(2)); for (int i=1;i<=e;i++) rmq[i][0]=euler[i]; for (int j=1;j<=lge;j++) for (int i=1;i<=e-(1<<j)+1;i++) if (high[rmq[i][j-1]]<high[rmq[i+(1<<j-1)][j-1]]) rmq[i][j]=rmq[i][j-1]; else rmq[i][j]=rmq[i+(1<<j-1)][j-1]; } int RMQ(int l,int r) { int lgr=(int)trunc(log(r-l+1)/log(2)); if (high[rmq[l][lgr]]<high[rmq[r-(1<<lgr)+1][lgr]]) return rmq[l][lgr]; else return rmq[r-(1<<lgr)+1][lgr]; } int lca(int x,int y) { x=pos[x],y=pos[y]; if (x>y) x^=y^=x^=y; return RMQ(x,y); }}t;char r[L+5];int n,q;int main(){ freopen("strings.in","r",stdin); freopen("strings.out","w",stdout); n=read(); for (int i=1,x,y;i<n;i++) { x=read(),y=read(); scanf("%s",r); t.insert(x,y,r); t.insert(y,x,r); } t.root[1]=0; t.calc(1); t.build(); q=read(); for (int i=1,x,y,z;i<=q;i++) { x=read(),y=read(); scanf("%s",r); z=t.lca(x,y); int ans=trie.query(r,t.root[x])+trie.query(r,t.root[y]); ans-=trie.query(r,t.root[z])*2; printf("%d\n",ans); } fclose(stdin); fclose(stdout);}
0 0
- [JSOI2015][JZOJ4061]字符串树
- 【JZOJ4061】【JSOI2015】字符串树
- Jzoj4061 字符串树
- 【JSOI2015】字符串树
- 【JSOI2015】字符串树
- 【JSOI2015】字符串树
- bzoj 4477: [Jsoi2015]字符串树
- JZOJ 4061. 【JSOI2015】字符串树
- bzoj 4477: [Jsoi2015]字符串树
- bzoj 4477: [Jsoi2015]字符串树
- bzoj 4477: [Jsoi2015]字符串树 可持久化线段树
- [BZOJ4477][JSOI2015]字符串树 可持久化Trie树
- [BZOJ]4477: [Jsoi2015]字符串树 可持久化trie
- JSOI2015
- JSOI2015 day1
- 【JSOI2015】非诚勿扰
- 记JSOI2015第一轮
- JSOI2015 Round2 Day2题解
- 莫队算法详解
- PHP程序在引号前自动加反斜杠的原因与处理办法
- javascript学习笔记_学习笔记6_javascript如何调试
- 单链表逆序2
- HDU 2602 捡骨头 【入门DP之01背包】
- [JSOI2015][JZOJ4061]字符串树
- 硬盘安装Ubuntu 15.10记录
- mac+Appium+java+IOS 自动化测试环境搭建
- 【智能路由器】让MT7620固件openwrt支持USB
- dagger2 + RxJava +Retrofit 学习笔记
- 【VBA】常用字符转换函数备忘
- Apache设置多端口,多IP映射多站点
- 坐在马桶上看算法:只有五行的Floyd最短路算法
- [Memcached]Memcached 的分布式算法