zoukankan      html  css  js  c++  java
  • POJ 4005 笛卡尔树+线段树+KMP

    题意:
    给出n个鼹鼠的编号(打乱顺序)排成一列,从第一个(非编号)鼹鼠开始挖洞,第2-n个鼹鼠在第一个鼹鼠挖洞的基础上挖洞,如果编号比之前的大就往右边走,否则往左边走,如果走不通(即左边或者右边没有洞),就自己挖洞,每只鼹鼠都会挖恰好一个洞。最终会形成一个二叉搜索树,得到这个树的dfs序列,把每一项都%2,最终得到一个01序列,与输入序列匹配,求输入序列在dfs序列中出现过多少次。

    (貌似说的不太清楚,看不懂的话可以去读原题,很容易看懂,我这英语水平都读懂了。。。就是表达不出来)

    思路:

    笛卡尔树,鼹鼠的排列顺序满足小根堆的性质,编号满足二叉搜索树的顺序,就可以构造了~

    最后kmp就可以了~

    PS:

    dfs和建树必须是非递归的,递归会暴栈(想想60万层)

    rmq其实更好,只不过我没能开下。就写了线段树

    笛卡尔树可以有O(n)的建树方法(除去排序),也非常简短,但是我不会。。。

    吐槽:

    这题递归三行改成非递归就成60行了。。。

    G++ wa,c++在poj2900ms卡时过,在hdu 4125   1800ms过

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <iostream>
      5 #include <algorithm>
      6 
      7 #define N 750010
      8 
      9 using namespace std;
     10 
     11 struct PO
     12 {
     13     int a,w;
     14 }po[N];
     15 
     16 struct TR
     17 {
     18     int u,l,r;
     19 }tr[N];
     20 
     21 struct Q
     22 {
     23     int bh,l,r;
     24 }q[N],wc;
     25 
     26 struct QQ
     27 {
     28     int bh,pd;
     29 }qq[N],we;
     30 
     31 int s[N],p,pos,n,cnt,tt,next[N],b[N],len,mx[N*2];
     32 
     33 char str[N];
     34 
     35 inline bool cmp(const PO &a,const PO &b)
     36 {
     37     return a.a<b.a;
     38 }
     39 
     40 inline int jmin(int x,int y)
     41 {
     42     if(po[x].w<po[y].w) return x;
     43     return y;
     44 }
     45 
     46 void build(int u,int l,int r)
     47 {
     48     if(l==r) {mx[u]=l;return;}
     49     int mid=(l+r)>>1;
     50     build(u<<1,l,mid);
     51     build(u<<1|1,mid+1,r);
     52     mx[u]=jmin(mx[u<<1],mx[u<<1|1]);
     53 }
     54 
     55 void query(int u,int L,int R,int l,int r)
     56 {
     57     if(L<=l&&r<=R) {pos=jmin(pos,mx[u]);return;}
     58     int mid=(l+r)>>1;
     59     if(L<=mid) query(u<<1,L,R,l,mid);
     60     if(R>mid) query(u<<1|1,L,R,mid+1,r);
     61 }
     62 
     63 void read()
     64 {
     65     scanf("%d",&n);
     66     for(int i=1;i<=n;i++)
     67     {
     68         scanf("%d",&po[i].a);
     69         po[i].w=i;
     70     }
     71     po[0].w=0x7f7f7f7f;
     72     sort(po+1,po+1+n,cmp);
     73     build(1,1,n);
     74 }
     75 
     76 void create()
     77 {
     78     cnt=1;
     79     int size=1;
     80     q[size].bh=1; q[size].l=1; q[size].r=n;
     81     while(size)
     82     {
     83         wc=q[size--];
     84         pos=0;
     85         query(1,wc.l,wc.r,1,n);
     86         tr[wc.bh].u=po[pos].a;
     87         if(wc.l<=pos-1)
     88         {
     89             tr[wc.bh].l=++cnt;
     90             q[++size].bh=cnt;
     91             q[size].l=wc.l;
     92             q[size].r=pos-1;
     93         }
     94         if(wc.r>=pos+1)
     95         {
     96             tr[wc.bh].r=++cnt;
     97             q[++size].bh=cnt;
     98             q[size].l=pos+1;
     99             q[size].r=wc.r;
    100         }
    101     }
    102 }
    103 
    104 void dfs()
    105 {
    106     int size=1;
    107     qq[size].bh=1; qq[size].pd=0;
    108     while(size)
    109     {
    110         we=qq[size];
    111         if(we.pd==0)
    112         {
    113             s[++p]=tr[we.bh].u&1;
    114             if(tr[we.bh].l!=-1)
    115             {
    116                 qq[size].pd=1;
    117                 qq[++size].bh=tr[we.bh].l;
    118                 qq[size].pd=0;
    119                 continue;
    120             }
    121             if(tr[we.bh].r!=-1)
    122             {
    123                 qq[size].pd=2;
    124                 qq[++size].bh=tr[we.bh].r;
    125                 qq[size].pd=0;
    126                 continue;
    127             }
    128         }
    129         if(we.pd==1)
    130         {
    131             s[++p]=tr[we.bh].u&1;
    132             if(tr[we.bh].r!=-1)
    133             {
    134                 qq[size].pd=2;
    135                 qq[++size].bh=tr[we.bh].r;
    136                 qq[size].pd=0;
    137                 continue;
    138             }
    139         }
    140         if(we.pd==2) s[++p]=tr[we.bh].u&1; 
    141         size--;
    142     }
    143 }
    144 
    145 void getnext()
    146 {
    147     next[1]=0;
    148     int i,j=0;
    149     for(i=2;i<=len;i++)
    150     {
    151         while(j>0&&b[j+1]!=b[i]) j=next[j];
    152         if(b[j+1]==b[i]) j+=1;
    153         next[i]=j;
    154     }
    155 }
    156 
    157 int kmp()
    158 {
    159     int i,j=0,num=0;
    160     for(i=1;i<=p;i++)
    161     {
    162         while(j>0&&b[j+1]!=s[i]) j=next[j];
    163         if(b[j+1]==s[i]) j+=1;
    164         if(j==len)
    165         {
    166             num++;
    167             j=next[j];
    168         }
    169     }
    170     return num;
    171 }
    172 
    173 void go()
    174 {
    175     memset(tr,-1,sizeof tr);
    176     create();
    177     p=0;
    178     dfs();
    179     scanf("%s",str+1);
    180     len=strlen(str+1);
    181     for(int i=1;i<=len;i++) b[i]=str[i]-'0';
    182     getnext();
    183     printf("%d\n",kmp());
    184 }
    185 
    186 int main()
    187 {
    188     scanf("%d",&tt);
    189     for(int i=1;i<=tt;i++)
    190     {
    191         read();
    192         printf("Case #%d: ",i);
    193         go();
    194     }
    195     //system("pause");
    196     return 0;
    197 }
    没有人能阻止我前进的步伐,除了我自己!
  • 相关阅读:
    20155227 《Java程序设计》实验四 Android开发基础设计实验报告
    20155227第十二周课堂实践
    2016-2017-2 20155227实验三《敏捷开发与XP实践》实验报告
    20155227 2016-2017-2 《Java程序设计》第十周学习总结
    2016-2017-2 20155227实验二《Java面向对象程序设计》实验报告
    20155226 实验三 敏捷开发与XP实践 实验报告
    20155226 mini DC 课堂测试补交
    20155226 2016-2017-2 《Java程序设计》第10周学习总结
    2015526 《Java程序设计》实验二实验报告
    20155226 2016-2017-2 《Java程序设计》第9周学习总结
  • 原文地址:https://www.cnblogs.com/proverbs/p/2721880.html
Copyright © 2011-2022 走看看