zoukankan      html  css  js  c++  java
  • bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3881

    对 S 建 SAM ,每个 T 会让 S 的 parent 树的链并答案+1;在 T 走每一步的时候,走到的节点用 LCT access 一下,就能找到该点到 parent 根的链。

    给链打标记。在 access 的过程中,如果遇到已经打过这个 T 标记的点,就停止 access 。

    注意实现的时候,在判断 fa[x] 有没有标记之前要先 splay(fa[x]) 。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ls c[cr][0]
    #define rs c[cr][1]
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    const int N=1e5+5,M=2e6+5,K=26;
    int n,ps[N],tot=1,c[M][K],tc[M][K],fl[M],q[M];
    int tim,dfn[M],fa[M],vl[M],tg[M],sta[M];
    char s[M];
    bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
    void cz(int cr)
    {
      if(!tg[cr])return; int w=tg[cr];tg[cr]=0;
      vl[ls]+=w; vl[rs]+=w;
      tg[ls]+=w; tg[rs]+=w;
      dfn[ls]=dfn[rs]=dfn[cr];///
    }
    void rotate(int x)
    {
      int y=fa[x],z=fa[y],d=(x==c[y][1]);
      if(!isrt(y))c[z][y==c[z][1]]=x;
      fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
      c[y][d]=c[x][!d]; c[x][!d]=y;
    }
    void splay(int x)
    {
      int top; sta[top=1]=x;
      for(int k=x;!isrt(k);k=fa[k])sta[++top]=fa[k];
      for(int i=top;i;i--)cz(sta[i]);
      for(int y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
        if(!isrt(y))
          ((y==c[z][0])^(x==c[y][0]))?rotate(x):rotate(y);
    }
    void access(int x)
    {
      splay(x); if(dfn[x]==tim)return;
      int t=0;
      while(1)
        {
          c[x][1]=t;
          if(!fa[x])
        { tg[x]++;vl[x]++;dfn[x]=tim;return;}
          splay(fa[x]);//splay first
          if(dfn[fa[x]]==tim)
        { tg[x]++;vl[x]++;dfn[x]=tim;return;}
          t=x; x=fa[x];
        }
    }
    void link(int x,int y){ fa[y]=x;}
    int Ins()
    {
      int cr=1,len=strlen(s+1);
      for(int i=1;i<=len;i++)
        {
          int w=s[i]-'a';
          if(!tc[cr][w])tc[cr][w]=++tot;
          cr=tc[cr][w];
        }
      return cr;
    }
    void get_fl()
    {
      int he=0,tl=0;
      for(int i=0,v;i<K;i++)
        if((v=tc[1][i]))
          {q[++tl]=v;fl[v]=1;link(1,v);}
        else tc[1][i]=1;
      while(he<tl)
        {
          int k=q[++he],pr=fl[k];
          for(int i=0,v;i<K;i++)
        if((v=tc[k][i]))
          { q[++tl]=v;fl[v]=tc[pr][i];link(tc[pr][i],v);}
        else tc[k][i]=tc[pr][i];
        }
    }
    void solve()
    {
      tim++; int cr=1,len=strlen(s+1);
      for(int i=1;i<=len;i++)
        {
          cr=tc[cr][s[i]-'a'];
          access(cr);
        }
    }
    int main()
    {
      n=rdn();
      for(int i=1;i<=n;i++)
        { scanf("%s",s+1); ps[i]=Ins();}
      get_fl();
      int Q=rdn(),op,x;
      while(Q--)
        {
          op=rdn();
          if(op==1)
        { scanf("%s",s+1); solve();}
          else
        {
          x=rdn(); x=ps[x];
          splay(x); printf("%d
    ",vl[x]);
        }
        }
      return 0;
    }
  • 相关阅读:
    MFC开发编程规范(二)
    Mysql日期和时间函数大全(转)
    php获取客户端IP地址的几种方法
    postgres 查看数据表和索引的大小
    PHP应用memcache函数详解
    css自动截取文字 兼容IE firefox Opera
    JavaScript在IE和Firefox浏览器下的7个差异兼容写法小结
    Zend_Auth与Zend_Acl访问控制链
    去除所有js,html,css代码问题
    [转]那些相见恨晚的 JavaScript 技巧
  • 原文地址:https://www.cnblogs.com/Narh/p/10804518.html
Copyright © 2011-2022 走看看