zoukankan      html  css  js  c++  java
  • 【bzoj4231】回忆树

    • 题解:

      • 树上的串匹配,模式串的总长$|S|$,令$overline {S} $为$S$的反串;
      • 对$S$和$overline {S} $分别建自动机
      • $u -> v$可以分成三个部分去统计
      • ①跨越了$lca(u, v)$的部分,长度不会超过$2|S|$,$kmp$暴力统计答案;
      • ②$(u,lca)$上不跨越$lca$的部分,差分变成两个到根的询问;
      • ②$(lca,v)$上不跨越$lca$的部分,差分变成两个到根的询问;
      • $dfs$原树并记录走到两个自动机的节点$x / y$,$BIT$维护$fail$树的子树和:
      • 进入时$add(x / y,1)$,回溯时$add(x /  y,-1)$;
      • ②在$overline {S} $里查,①在$S$里查即可处理所有询问;
      • (突然发现似乎不用建两个自动机,直接建在一起就好了TAT所以别学大米饼丑陋的代码)
      • 一个弱化版:bzoj3881,另外树剖$lca$常数小,好些,点分治常用$rmq$求$lca$;
      •   1 #include<bits/stdc++.h>
          2 #define rg register 
          3 #define il inline
          4 using namespace std;
          5 const int N=100010,M=300010;
          6 int n,m,o=1,hd[N],Hd[N],O=1,tp[N],sz[N],sn[N],dfn[N],idx;
          7 int q[N],head,tail,fa[N],f[N],pos[N],dep[N],ans[N];
          8 struct Edge{int v,nt,c;}E[N<<1];
          9 struct Qury{int p,x,y,nt;}Q[N<<2];
         10 char s[N],t[N],fm[N];
         11 il void adde(int u,int v,int c){
         12     E[o]=(Edge){v,hd[u],c};hd[u]=o++;
         13     E[o]=(Edge){u,hd[v],c};hd[v]=o++;
         14 }
         15 il void addq(int u,int p,int x,int y){
         16     Q[O]=(Qury){p,x,y,Hd[u]};Hd[u]=O++;
         17 }
         18 void dfs1(int u,int F){
         19     sz[u]=1;sn[u]=0;
         20     dep[u]=dep[fa[u]=F]+1;
         21     for(rg int i=hd[u];i;i=E[i].nt){
         22         int v=E[i].v;
         23         if(v==F)continue;
         24         fm[v]=E[i].c+'a';
         25         dfs1(v,u);
         26         sz[u]+=sz[v];
         27         if(sz[v]>sz[sn[u]])sn[u]=v;
         28     }
         29 }
         30 void dfs2(int u,int T){
         31     dfn[pos[u]=++idx]=u;tp[u]=T;
         32     if(sn[u])dfs2(sn[u],T);
         33     for(rg int i=hd[u];i;i=E[i].nt){
         34         int v=E[i].v;
         35         if(v==fa[u]||v==sn[u])continue;
         36         dfs2(v,v);
         37     }
         38 } 
         39 il int go(int u,int d){
         40     int tu=tp[u];
         41     while(dep[u]-dep[tu]<d){
         42         d-=dep[u]-dep[tu]+1;
         43         u=fa[tu],tu=tp[u];
         44     }
         45     return dfn[pos[tu]+dep[u]-dep[tu]-d];
         46 }
         47 il int lca(int u,int v){
         48     int tu=tp[u],tv=tp[v];
         49     while(tu!=tv)if(dep[tu]>dep[tv])u=fa[tu],tu=tp[u];
         50     else v=fa[tv],tv=tp[v];
         51     return dep[u]<dep[v]?u:v;
         52 }
         53 il int kmp(int x,int y,int z,int ls){
         54     int lt=0,tl=0,re=0;
         55     while(dep[x]>dep[z])t[++lt]=fm[x],x=fa[x];
         56     tl=lt=lt+dep[y]-dep[z];    
         57     while(dep[y]>dep[z])t[tl--]=fm[y],y=fa[y];
         58     if(lt<ls)return 0;
         59     f[0]=f[1]=0;
         60     for(rg int i=1,j=0;i<ls;f[++i]=j){
         61         while(j&&s[i+1]!=s[j+1])j=f[j];
         62         if(s[i+1]==s[j+1])j++;
         63     }
         64     for(rg int i=1,j=0;i<=lt;i++){
         65         while(j&&t[i]!=s[j+1])j=f[j];
         66         if(t[i]==s[j+1])j++;
         67         if(j==ls)re++,j=f[j];
         68     }
         69     return re;
         70 } 
         71 struct AC{
         72     int cnt,fl[M],fa[M],st[M],ed[M],idx,c[M],ch[M][26],pos[N],hd[N],o;
         73     struct Edge{int v,nt;}E[N];
         74     il void adde(int u,int v){E[o]=(Edge){v,hd[u]};hd[u]=o++;}
         75     il void add(int x,int y){for(;x<=idx;x+=x&-x)c[x]+=y;}
         76     il int ask(int x){int re=0;for(;x;x-=x&-x)re+=c[x];return re;}
         77     il void ins(int cur,int l){
         78         int x=0;
         79         for(int i=1,y;i<=l;i++){
         80             if(!ch[x][y=s[i]-'a'])ch[x][y]=++cnt;
         81             x=ch[x][y];
         82         }pos[cur]=x;
         83     }
         84     il void dfs(int u){
         85         st[u]=++idx;
         86         for(rg int i=hd[u];i;i=E[i].nt)dfs(E[i].v);
         87         ed[u]=idx;
         88     }
         89     il void bfs(){
         90         o=1;head=tail=0;
         91         for(int i=0;i<26;i++)if(ch[0][i]){
         92             q[++tail]=ch[0][i];
         93             adde(0,ch[0][i]);
         94         }
         95         while(head<tail){
         96             int u=q[++head];
         97             for(rg int i=0;i<26;i++){
         98                 int&v=ch[u][i];
         99                 if(!v){v=ch[fl[u]][i];continue;}
        100                 fl[v]=ch[fl[u]][i];
        101                 q[++tail]=v;
        102                 adde(fl[v],v);
        103             }
        104         } 
        105         dfs(0);
        106     }
        107     il int que(int x){return ask(ed[pos[x]]) - ask(st[pos[x]]-1);}
        108 }ac[2];
        109 void dfs3(int u,int y0,int y1){
        110     ac[0].add(ac[0].st[y0],1);
        111     ac[1].add(ac[1].st[y1],1);
        112     for(int i=Hd[u];i;i=Q[i].nt){
        113         ans[Q[i].x]+=ac[Q[i].p].que(Q[i].x)*Q[i].y;
        114     }
        115     for(int i=hd[u];i;i=E[i].nt){
        116         int v=E[i].v , c=E[i].c; 
        117         if(E[i].v==fa[u])continue;
        118         dfs3(v,ac[0].ch[y0][c],ac[1].ch[y1][c]);
        119     }
        120     ac[0].add(ac[0].st[y0],-1);
        121     ac[1].add(ac[1].st[y1],-1);
        122 }
        123 int main(){
        124     #ifndef ONLINE_JUDGE
        125     freopen("bzoj4231.in","r",stdin);
        126     freopen("bzoj4231.out","w",stdout); 
        127     #endif 
        128     scanf("%d%d",&n,&m);
        129     for(rg int i=1;i<n;i++){
        130         int u,v;
        131         scanf("%d%d%s",&u,&v,s+1);
        132         adde(u,v,s[1]-'a');
        133     } 
        134     dfs1(1,0);dfs2(1,1);
        135     for(rg int i=1;i<=m;i++){
        136         int u,v,w,l,t1,t2;
        137         scanf("%d%d%s",&u,&v,s+1);
        138         w=lca(u,v);
        139         l=strlen(s+1);
        140         t1=go(u,max(0,dep[u]-dep[w]-l+1));
        141         t2=go(v,max(0,dep[v]-dep[w]-l+1));
        142         ans[i]+=kmp(t1,t2,w,l);
        143         ac[0].ins(i,l);
        144         for(rg int j=1;j<=l>>1;j++)swap(s[j],s[l-j+1]);
        145         ac[1].ins(i,l);
        146         if(t1!=u)addq(u,1,i,1),addq(t1,1,i,-1);
        147         if(t2!=v)addq(v,0,i,1),addq(t2,0,i,-1);
        148     }
        149     ac[0].bfs();
        150     ac[1].bfs();
        151     dfs3(1,0,0);
        152     for(rg int i=1;i<=m;i++){printf("%d
        ",ans[i]);}
        153     return 0;
        154 }
        bzoj4231

    $lca(q[i-1],q[i])$

  • 相关阅读:
    背景图片拉伸显示CSS
    可序列化对象和byte[]数组之间的互转
    简单web性能测试工具——ab命令(ApacheBench)
    测试人员必须掌握的linu常用命令
    robot framework 如何处理循环条件下面的变量自增
    robot framework 的关键字Continue For Loop 用法
    robot framework 的AutoItLibrary常用关键字
    robot framework 关键字Switch Browser和Select Window的区别
    robot framework 接口测试 http协议post请求json格式
    robot framework 怎么验证搜索无记录,页面元素不存在
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10241742.html
Copyright © 2011-2022 走看看