zoukankan      html  css  js  c++  java
  • bzoj 2434 阿狸的打字机 fail树的性质

          如果a串是另b串的后缀,那么在trie图上沿着b的fail指针走一定可以走到a串。

          而a串在b串里出现多少次就是它是多少个前缀的后缀。

          所以把fail边反向建树维护个dfs序就行了。

          并不是很难。。。但没想出来TAT

         

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #define N 200005
      6 #define inf 0x3f3f3f3f
      7 using namespace std;
      8 int n;
      9 int ch[N][2], fa[N];
     10 int a[N];
     11 int mn[N],zhi[N],size[N];
     12 void push_up(int x)
     13 {
     14     size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;
     15     mn[x] = min(zhi[x], min(mn[ch[x][0]], mn[ch[x][1]])); return;
     16 }
     17 int rev[N];
     18 void push_down(int x)
     19 {
     20     if (rev[x])
     21     {
     22         rev[x] ^= 1; rev[ch[x][1]] ^= 1; rev[ch[x][0]] ^= 1;
     23         swap(ch[x][0], ch[x][1]);
     24     }
     25     return;
     26 }
     27 void rotate(int p)
     28 {
     29     int q = fa[p], y = fa[q], x = (ch[q][1] == p);
     30     ch[q][x] = ch[p][x ^ 1]; fa[ch[q][x]] = q;
     31     ch[p][x ^ 1] = q; fa[q] = p;
     32     fa[p] = y;
     33     if (y)
     34     {
     35         if (ch[y][1] == q)ch[y][1] = p;
     36         else ch[y][0] = p;
     37     }
     38     push_up(q); return;
     39 }
     40 int root;
     41 void splay(int x,int yy)
     42 {
     43     for (int y; y = fa[x]; rotate(x))
     44     {
     45         if (y == yy)break;
     46         if (fa[y] != yy)
     47         {
     48             if ((ch[fa[y]][0] == y) ^ (ch[y][0] == x))rotate(x);
     49             else rotate(y);
     50         }
     51     }
     52     push_up(x);
     53     if (!yy)root = x;
     54 }
     55 int cnt;
     56 int find(int k, int x)
     57 {
     58     push_down(k);
     59     if (mn[ch[k][0]] == x)
     60     {
     61         return find(ch[k][0], x);
     62     }
     63     if (zhi[k] == x)return size[ch[k][0]] + 1;
     64     return find(ch[k][1], x) + size[ch[k][0]] + 1;
     65 }
     66 int fd(int k, int x)
     67 {
     68     push_down(k);
     69     if (size[ch[k][0]] + 1 == x)return k;
     70     if (size[ch[k][0]] + 1 >= x)return fd(ch[k][0],x);
     71     return fd(ch[k][1], x - size[ch[k][0]] - 1);
     72 }
     73 struct node
     74 {
     75     int yuan,z;
     76     friend bool operator < (node aa,node bb)
     77     {
     78         if(aa.z!=bb.z)return aa.z<bb.z;
     79         return aa.yuan<bb.yuan;
     80     }
     81 }s[N];
     82 int yin[N];
     83 int main()
     84 {
     85     scanf("%d", &n); mn[0] = inf;
     86     for (int i = 1; i <= n; i++)
     87     {
     88         s[i].yuan=i;scanf("%d",&s[i].z);
     89     }
     90     sort(s+1,s+n+1);
     91     for(int i=1;i<=n;i++)
     92     {
     93         a[s[i].yuan]=i;
     94     }
     95     root = 1; a[n + 1] = inf; 
     96     ch[1][1] = 2; zhi[1] = a[1]; size[1] = n + 1;
     97     for (int i = 2; i <= n + 1; i++)
     98     {
     99         size[i] = n - i + 2;
    100         zhi[i] = a[i]; fa[i] = i - 1; ch[i - 1][1] = i;
    101     }
    102     for (int i = n + 1; i >= 1; i--)push_up(i);
    103     splay(n, 0);
    104     for (int i = 1; i <= n; i++)
    105     {
    106         int y = find(root, mn[root]);
    107         if(i!=n)printf("%d ",y+(i-1));
    108         else printf("%d",y+(i-1));
    109         int t = fd(root, y+1);
    110         splay(t, 0);
    111         rev[ch[t][0]] ^= 1;
    112         t = fd(root, 2);
    113         splay(t, 0);
    114         ch[t][0] = 0;
    115         push_up(t);
    116     }
    117     puts("");
    118     return 0;
    119 }
  • 相关阅读:
    jQuery 源码解析(二十四) DOM操作模块 包裹元素 详解
    jQuery 源码解析(二十三) DOM操作模块 替换元素 详解
    jQuery 源码解析(二十二) DOM操作模块 复制元素 详解
    jQuery 源码分析(二十一) DOM操作模块 删除元素 详解
    jQuery 源码分析(二十) DOM操作模块 插入元素 详解
    jQuery 源码分析(十九) DOM遍历模块详解
    python 简单工厂模式
    python 爬虫-协程 采集博客园
    vue 自定义image组件
    微信小程序 image组件坑
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6235569.html
Copyright © 2011-2022 走看看