• 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 }
  • 相关阅读:
    python之类的详解
    flask中cookie和session介绍
    Flask数据库的基本操作
    CSRF原理
    Ajax.2
    浅谈Ajax
    Django中的缓存机制
    Django简介
    HTTP协议
    web应用
  • 原文地址:https://www.cnblogs.com/ezyzy/p/6235569.html
Copyright © 2020-2023  润新知