bzoj4477: [Jsoi2015]字串樹(主席樹+Hash+Lca)
題目傳送門
。
解法:
長度小於等於10?
hash+主席樹啊!!!
然後我就苦逼了的碼了一個鐘。
然後跑的賊慢倒數第三。。
網上的據說全是可持久化字典樹??
什麼鬼我不會。。
只能用主席樹了。
建10棵主席樹來維護長度不同的字首。
然後樹上主席樹求一下就好了?
程式碼實現:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
struct node {int lc,rc,c;}t[11][2100000];int rt[11][110000],cnt;
void build(int c,int &u,int l,int r,int p) {
if(u==0)u=++cnt;t[c][u].c++;
if(l==r)return ;int mid=(l+r)/2;
if(p<=mid)build(c,t[c][u].lc,l,mid,p);
else build(c,t[c][u].rc,mid+1,r,p);
}
void Merge(int c,int &u1,int u2) {
if(u1==0){u1=u2;return ;}if(u2==0)return ;
t[c][u1].c+=t[c][u2].c;
Merge(c,t[c][u1].lc,t[c][u2].lc);
Merge(c,t[c][u1].rc,t[c][u2].rc);
}
struct trnode {int x,y,next;}a[210000],e[110000];int len,last[110000];
char ss[110000][11];
void ins(int x,int y) {len++;a[len].x=x;a[len].y=y;a[len].next=last[x];last[x]=len;}
int mx[21][110000],dep[110000],n;
void dfs(int x) {
for(int k=last[x];k;k=a[k].next) {
int y=a[k].y;
if(y!=mx[0][x]) {dep[y]=dep[x]+1;mx[0][y]=x;dfs(y);}
}
}
unsigned int base=222;
int bin[21];
void work() {
bin[0]=1;for(int i=1;i<=20;i++)bin[i]=bin[i-1]*2;
for(int j=1;j<=20;j++)for(int i=1;i<=n;i++)if(dep[i]>=bin[j]) {
mx[j][i]=mx[j-1][mx[j-1][i]];
}
}
int lca(int x,int y) {
if(dep[x]>dep[y])swap(x,y);
for(int i=20;i>=0;i--)if(dep[y]-dep[x]>=bin[i])y=mx[i][y];
if(x==y)return x;
for(int i=20;i>=0;i--) if(dep[x]>=bin[i]&&mx[i][x]!=mx[i][y]) {
x=mx[i][x];y=mx[i][y];
}return mx[0][x];
}
int find(int c,int u1,int u2,int u3,int l,int r,int p) {
if(t[c][u1].c+t[c][u2].c-2*t[c][u3].c==0)return 0;
if(l==r)return t[c][u1].c+t[c][u2].c-2*t[c][u3].c;
int mid=(l+r)/2;
if(p<=mid)return find(c,t[c][u1].lc,t[c][u2].lc,t[c][u3].lc,l,mid,p);
else return find(c,t[c][u1].rc,t[c][u2].rc,t[c][u3].rc,mid+1,r,p);
}
struct edge {int id,len,x;}S[1100000];
bool cmp(edge n1,edge n2) {return n1.x<n2.x;}
int s[1100000],tt=0;
void merge(int x) {
for(int k=last[x];k;k=a[k].next) {
int y=a[k].y;
if(y!=mx[0][x]) {
for(int i=1;i<=10;i++)Merge(i,rt[i][y],rt[i][x]);
merge(y);
}
}
}
int pos(int x) {
int l=1,r=tt,mid,ans=-1;
while(l<=r) {
int mid=(l+r)/2;
if(S[mid].x<=x) {
if(S[mid].x==x)ans=mid;
l=mid+1;
}else r=mid-1;
}return ans;
}char st[11];
int main() {
scanf("%d",&n);len=0;memset(last,0,sizeof(last));
for(int i=1;i<n;i++) {
scanf("%d%d%s",&e[i].x,&e[i].y,ss[i]+1);
ins(e[i].x,e[i].y);ins(e[i].y,e[i].x);
}dep[1]=0;mx[0][1]=0;dfs(1);work();
for(int i=1;i<n;i++)if(dep[e[i].x]>dep[e[i].y])swap(e[i].x,e[i].y);
tt=0;
for(int K=1;K<=10;K++) {
for(int i=1;i<n;i++) {
unsigned int ans=0;
if(strlen(ss[i]+1)<K)continue;
for(int j=1;j<=K;j++) ans=ans*base+ss[i][j]-'a'+1;
S[++tt].x=ans;S[tt].id=i;S[tt].len=K;
}
}
sort(S+1,S+1+tt,cmp);
int tot=0;
for(int i=1;i<=tt;i++) {
if(S[i].x!=S[i-1].x)tot++;s[i]=tot;
}
for(int i=1;i<=10;i++) {
cnt=0;
for(int j=1;j<=tt;j++) {
if(S[j].len!=i)continue;
int k=S[j].id;
build(i,rt[i][e[k].y],1,tot,s[j]);
}
}
merge(1);
int m;scanf("%d",&m);
while(m--) {
int x,y;scanf("%d%d%s",&x,&y,st+1);
int T=strlen(st+1);
unsigned int Hash=0;
for(int i=1;i<=T;i++) Hash=Hash*base+st[i]-'a'+1;
int X=pos(Hash);
if(X==-1)printf("0\n");
else {
int Lca=lca(x,y);
printf("%d\n",find(T,rt[T][x],rt[T][y],rt[T][Lca],1,tot,s[X]));
}
}
return 0;
}
相關文章
- 動態主席樹模板
- 演算法隨筆——主席樹(可持久化線段樹)演算法持久化
- 【資料結構】淺談主席樹資料結構
- SPOJ TTM To the moon(主席樹+區間操作)
- bzoj3439: Kpm的MC密碼(主席樹+DFS序+字典樹)密碼
- BZOJ4299: Codechef FRBSUM(主席樹)
- 2024年3月21日 懸繩法 + 珂朵莉樹(ODT) + 主席樹
- SPOJ DQUERY (離線數狀陣列||線上主席樹)陣列
- Bzoj 1901 Zju2112 Dynamic Rankings(樹狀陣列+主席樹)陣列
- hdu 2665 可持久化線段樹求區間第K大值(函式式線段樹||主席樹)持久化函式
- CF 220E Little Elephant and Inversions(主席樹+two points)
- bzoj3110: [Zjoi2013]K大數查詢(主席樹+樹狀陣列)陣列
- Trie樹:字串頻率統計排序字串排序
- hdu 3973 字串hash+線段樹字串
- bzoj4448: [Scoi2015]情報傳遞(主席樹+Lca)
- bzoj5178: [Jsoi2011]棒棒糖(主席樹)JS
- bzoj1146: [CTSC2008]網路管理Network(dfs序+主席樹+樹狀陣列)陣列
- 樹套樹
- bzoj2809: [Apio2012]dispatching(DFS序+主席樹)API
- 字串陣列轉為樹形結構字串陣列
- 【字串演算法】字典樹詳解字串演算法
- 字串演算法--$\mathcal{KMP,Trie}$樹字串演算法KMP
- 多路查詢樹(2-3 樹、2-3-4 樹、B 樹、B+ 樹)
- bzoj5177: [Jsoi2013]貪心的導遊(主席樹)JS
- bzoj3932: [CQOI2015]任務查詢系統(主席樹)
- 二叉樹、B樹以及B+樹二叉樹
- 平衡二叉樹,B樹,B+樹二叉樹
- 淺談樹形結構的特性和應用(上):多叉樹,紅黑樹,堆,Trie樹,B樹,B+樹...
- bzoj2733: [HNOI2012]永無鄉(並查集+主席樹)並查集
- 資料結構之樹( 線段樹,字典樹)資料結構
- 資料結構之樹結構概述(含滿二叉樹、完全二叉樹、平衡二叉樹、二叉搜尋樹、紅黑樹、B-樹、B+樹、B*樹)資料結構二叉樹
- B樹(多路查詢樹)
- HDU 5469 Antonidas(樹上的字串匹配/搜尋)字串匹配
- 樹(1)--樹和二叉樹的基本定義二叉樹
- 資料結構之MySQL獨愛B+樹(二叉樹、AVL樹、紅黑樹、B樹對比)資料結構MySql二叉樹
- 資料結構中的樹(二叉樹、二叉搜尋樹、AVL樹)資料結構二叉樹
- 雜湊,二叉樹,紅黑樹,B樹,B+樹,LSM樹等資料結構做索引比較二叉樹資料結構索引
- 將多個路徑字串轉換成XML文件樹字串XML