【bzoj2754】【scoi2012】喵星球上的点名

    • 1.首先可以被很多暴力给搞过去;我以前也是这样水过去的
    • 2.ac自动机
      • 2.1
      • 抽离fail树
      • 对点名建自动机,建$fail$树的时候只保留询问节点;
      • 对于一个喵,子串==在自动机里匹配到的所有节点的$fail$祖先并
      • 把姓和名都放到里面去跑,得到所有的点,需要把这些点在新的$fail$树里的祖先全部标记
      • 具体按照dfs序排序,每个点$q[i]$的贡献就是$lca(q[i-1],q[i])$到$q[i]$那段
      • 统计第一问用树上差分$q[i]$处$++$,$lca(q[i-1],q[i])$处$--$,具体第二问直接记录每个点到根有多少次点名统计直接相减;
      • $O(N \ log N)$
      •   1 #include<bits/stdc++.h>
          2 #define rg register
          3 #define il inline 
          4 #define Run(i,l,r) for(rg int i=l;i<=r;i++)
          5 #define Don(i,l,r) for(rg int i=l;i>=r;i--)
          6 using namespace std;
          7 const int N=200010;
          8 int n,m,o=1,hd[N],a[N],b[N],s[N],tot,fl[N],fa[N],st[N],ed[N],idx;
          9 int val[N],vis[N],que[N],head,tail,sz,cnt,size[N],tp[N],dep[N],pos[N],ans[N],deep[N];
         10 il bool cmp(const int&x,const int&y){return st[x]<st[y];}
         11 map<int,int>ch[N];
         12 map<int,int>::iterator it;
         13 struct Edge{int v,nt;}E[N];
         14 il void adde(int u,int v){E[o]=(Edge){v,hd[u]};hd[u]=o++;}
         15 il char gc(){
         16     static char*p1,*p2,s[1000000];
         17     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
         18     return(p1==p2)?EOF:*p1++;
         19 }
         20 il int rd(){
         21     int x=0,f=1; char c=gc();
         22     while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
         23     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
         24     return x*f;
         25 }
         26 void get_fl(){
         27     for(it=ch[0].begin();it!=ch[0].end();it++){
         28         int v=it->second;
         29         que[++tail]=v;
         30         if(vis[v])adde(fa[v],v),size[v]=1;
         31     }
         32     while(head < tail){
         33         int u=que[++head];
         34         for(it = ch[u].begin();it!=ch[u].end();it++){
         35             int v = it->second, c = it->first, w=fl[u];
         36             while(w&&!ch[w].count(c))w=fl[w];
         37             if(!ch[w].count(c))fl[v]=0;
         38             else fl[v]=ch[w][c];
         39             if(vis[fl[v]])fa[v]=fl[v];
         40             else fa[v]=fa[fl[v]];
         41             que[++tail]=v;
         42             if(vis[v])adde(fa[v],v),size[v]=1;
         43         }
         44     }
         45     Don(i,tail,1)size[fa[que[i]]]+=size[que[i]];
         46 }
         47 void dfs(int u,int T){
         48     int son=0;
         49     st[u]=++idx;tp[u]=T;
         50     dep[u]=dep[fa[u]]+1;
         51     deep[u]=deep[fa[u]]+vis[u];
         52     for(int i=hd[u];i;i=E[i].nt){
         53         int v=E[i].v;
         54         if(!son||size[v]>size[son])son=v;
         55     }
         56     if(son)dfs(son,T);
         57     for(int i=hd[u];i;i=E[i].nt){
         58         int v=E[i].v;
         59         if(son!=v)dfs(v,v);
         60     }
         61     ed[u]=idx;
         62 }
         63 il int lca(int x,int y){
         64     int tx=tp[x],ty=tp[y];
         65     while(tx!=ty){
         66         if(dep[tx]<dep[ty])y=fa[ty],ty=tp[y]; 
         67         else x=fa[tx],tx=tp[x];
         68     }
         69     return dep[x]<dep[y]?x:y;
         70 }
         71 void find(int len){
         72     int x = 0 , c;
         73     Run(i,1,len){
         74         c = s[tot+i];
         75         while(x&&!ch[x].count(c))x=fl[x];
         76         if(!ch[x].count(c))x=0;
         77         else x=ch[x][c];
         78         if(vis[x])que[++tail]=x;
         79         else if(fa[x])que[++tail]=fa[x];
         80     }
         81     tot+=len;
         82 }
         83 void dfs(int u){
         84     for(int i=hd[u];i;i=E[i].nt)
         85         dfs(E[i].v),val[u]+=val[E[i].v];
         86 }
         87 int main(){
         88     freopen("bzoj2754.in","r",stdin);
         89     freopen("bzoj2754.out","w",stdout);
         90     n=rd(); m=rd();
         91     Run(i,1,n){
         92         a[i]=rd();Run(j,1,a[i])s[++tot]=rd();
         93         b[i]=rd();Run(j,1,b[i])s[++tot]=rd();
         94     }
         95     Run(i,1,m){
         96         int x=rd(),u=0,y;
         97         Run(j,1,x){
         98             if(!ch[u][y=rd()])ch[u][y]=++sz;
         99             u=ch[u][y];
        100         }
        101         vis[pos[i]=u]++;
        102     }
        103     get_fl();
        104     dfs(0,0);
        105     tot=0;
        106     Run(i,1,n){
        107         tail=0;
        108         find(a[i]),find(b[i]);
        109         if(!tail)continue;
        110         sort(que+1,que+tail+1,cmp);
        111         head=0;
        112         Run(j,1,tail){
        113             if(!head||ed[que[j]]>ed[que[head]])head++;
        114             que[head]=que[j];
        115         }
        116         tail=head;
        117         val[0]--,val[que[1]]++;
        118         ans[i]+=deep[que[1]]; 
        119         Run(j,2,tail){
        120             int tmp = lca(que[j-1],que[j]);
        121             val[tmp]--,val[que[j]]++; 
        122             ans[i] += deep[que[j]] - deep[tmp];
        123         }
        124     }
        125     dfs(0);
        126     Run(i,1,m)printf("%d\n",val[pos[i]]);
        127     Run(i,1,n)printf("%d ",ans[i]);
        128     return 0;
        129 }
        AC

相关文章:

  • 2022-03-09
  • 2021-06-15
  • 2021-12-06
  • 2021-11-21
  • 2022-12-23
猜你喜欢
  • 2022-03-05
  • 2021-12-09
  • 2021-12-17
  • 2021-06-10
  • 2021-10-04
  • 2021-11-30
相关资源
相似解决方案