• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            算法學社
            記錄難忘的征途
            posts - 141,comments - 220,trackbacks - 0

            題目簡介:

                給一個長度為N(N<600,000)的序列,讓你按順序插入靜態二叉樹。然后DFS出一個序列,問某個模式串在這個序列中出現了幾次?

            吐槽:

                被KMP卡了一個晚上是什么水平? 數組開小了WA了一下午是什么水平?

            算法分析:

                比較難想的是如何實現這個靜態二叉樹,因為要一個DFS序列,所以組織靜態二叉樹是不可逃避的了。
                這里用到一個結論,就是新插入的數的父親,要么是比它大的最小的那個元素,要么是比它小的最大的那個元素。
                然后套一個KMP就水過了。。。。
             1 #include<iostream>
             2 #include<cstdio>
             3 #include<cstring>
             4 #include<cassert>
             5 using namespace std;
             6 const int N = 600005;
             7 template <typename T> inline void chkmin(T &a,T b){if(a>b) a=b;}
             8 template <typename T> inline void chkmax(T &a,T b){if(a<b) a=b;}
             9 bool ch[N<<2];
            10 char parten[10000];
            11 int nxt[N],seg[N<<2][2], stk[N], vis[N], hash[N];
            12 const int inf = ~0u>>2;
            13 struct tree{
            14     int l,r,v;
            15     tree(){}
            16     tree(int _l,int _r,int _v) : l(_l), r(_r), v(_v) {}
            17 } num[N];
            18 int n,len;
            19 int main(){
            20     int test,M;
            21     cin >> test;
            22     for(int _=1;_<=test;_++){
            23         cin >> n;
            24         int v,val;
            25         for(int i=30;i>=0;i--) if((1<<i)>=n) M = 1<<i;
            26         for(int i=0;i<2*M;i++) seg[i][1] = -1, seg[i][0] = inf;
            27         for(int i=0;i<n;i++){
            28             scanf("%d",&v);
            29             val = v;
            30             hash[val] = i;
            31             if(i==0) {
            32                 num[0] = tree(-1,-1,v); 
            33                 v += M-1;
            34                 while(v){seg[v][0] = seg[v][1] = val;v>>=1;}
            35                 continue;
            36             }
            37             num[i] = tree(-1,-1,v);
            38             int mn = -1, mx = inf;
            39             for(v += M-1; v; v>>=1){
            40                 chkmin(seg[v][0],val);
            41                 chkmax(seg[v][1],val);
            42                 if(v&1) chkmax(mn,seg[v^1][1]);
            43                 else chkmin(mx, seg[v^1][0]);
            44             }
            45             //cout<<val<<" "<<mn<<" "<<mx<<endl;
            46             if(mn == -1 || num[hash[mn]].r !=-1){
            47                 num[hash[mx]].l = i;
            48             } else num[hash[mn]].r = i;
            49         }
            50         len = 0;
            51         
            52         for(int i=0;i<n;i++) vis[i] = 0;
            53         int tp = 0,u;stk[0] =0;
            54         while(!vis[0]) {
            55             u = stk[tp];
            56             ch[len++] = num[u].v & 1;
            57             v = num[u].l;
            58             if(v!=-1 && !vis[v]) {stk[++tp] = v; continue;}
            59             v = num[u].r;
            60             if(v!=-1 && !vis[v]) {stk[++tp] = v; continue;}
            61             tp--;
            62             vis[u] = 1;
            63         }
            64 //        for(int i=0;i<len;i++) cout<<ch[i]<<" ";cout<<endl;
            65         
            66         scanf("%s",parten);
            67         nxt[0] = -1; int m = strlen(parten);
            68         int j = -1;
            69         for(int i=0;i<m;i++) parten[i] -='0';
            70         for(int i=1;i<m;i++){
            71             while(j>=0 && parten[i]!=parten[j+1])    
            72                 j=nxt[j];
            73             if(parten[i]==parten[j+1]) j++; 
            74             nxt[i] = j;
            75         }
            76 //        for(int i=0;i<m;i++) cout<<nxt[i]<<" "; cout<<endl;
            77         int ans = 0; j = -1;
            78         for(int i=0;i<len;i++){
            79 //            cout<<j<<" ";
            80             while(j>=0 && parten[j+1]!=ch[i]) j = nxt[j]; 
            81             if(parten[j+1]==ch[i]) 
            82                 j++;
            83             if(j == m-1) {
            84                 ans++;
            85                 j = nxt[j];
            86             }
            87         }
            88         printf("Case #%d: %d\n",_,ans);
            89     }
            90 }
            91 
            posted on 2012-07-02 15:14 西月弦 閱讀(614) 評論(0)  編輯 收藏 引用
            无码日韩人妻精品久久蜜桃| 国产精品99久久久久久人| 国产精品99久久久久久宅男| 久久影视综合亚洲| 久久综合给久久狠狠97色 | 国产精品久久久久久搜索| 国产成人久久精品一区二区三区| 四虎久久影院| 99久久无码一区人妻| 久久综合给合久久狠狠狠97色| 国产精品久久久久久福利漫画| 久久伊人五月天论坛| 无码人妻精品一区二区三区久久 | 久久精品国产精品亚洲精品| 久久久久亚洲AV成人网人人网站 | 一本久久a久久精品综合香蕉 | 欧美亚洲国产精品久久蜜芽| 久久精品国产亚洲av麻豆色欲| 久久这里有精品| 欧美精品丝袜久久久中文字幕 | 国产午夜福利精品久久| 亚洲AV无码久久精品蜜桃| 国产精品成人精品久久久| 香蕉久久av一区二区三区| 国产精品久久久久久久久久影院 | 日本加勒比久久精品| 亚洲午夜久久久精品影院| 欧美亚洲色综久久精品国产| 一本大道久久东京热无码AV| 久久精品这里只有精99品| 欧美午夜A∨大片久久| 88久久精品无码一区二区毛片| 久久超乳爆乳中文字幕| 午夜天堂精品久久久久| 99久久精品国产一区二区| 国产精品久久久久无码av| 久久99热只有频精品8| 久久99精品久久久久久hb无码| 综合人妻久久一区二区精品| 久久人人爽人人人人爽AV| 久久精品综合网|