• <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>

            2010 天津賽區(qū)G hdu 3726 splay

            哎,一道裸splay的題目,網(wǎng)上竟然木有解題報(bào)告。我第一次寫(xiě)splay,犯了很多很多NC的錯(cuò)誤。。調(diào)了有一個(gè)下午,最后寫(xiě)了個(gè)測(cè)試模塊+生成了隨機(jī)數(shù)據(jù),才發(fā)現(xiàn)錯(cuò)誤。
            說(shuō)說(shuō)我的失誤吧。。
            1、首先zig zag實(shí)現(xiàn)的時(shí)候一定要配對(duì),不能亂,加個(gè)兒子節(jié)點(diǎn)就要把兒子節(jié)點(diǎn)的父親節(jié)點(diǎn)同時(shí)初始化好
            2、新加入節(jié)點(diǎn)的size域及其祖先的size域名不用調(diào)整,會(huì)在splay過(guò)程中自動(dòng)修正完畢
            3、千萬(wàn)別要試圖將一顆子樹(shù)的根節(jié)點(diǎn)插入到另外一棵樹(shù)中,以為將兩棵樹(shù)給合并住了。。BST的定義是左子樹(shù)中的所有節(jié)點(diǎn)嚴(yán)格小于根節(jié)點(diǎn),而不僅僅是左兒子節(jié)點(diǎn),右子樹(shù)亦同。

            然后針對(duì)本題說(shuō)說(shuō),要倒過(guò)來(lái)操作,不斷的將連通分支合并,相當(dāng)于合并兩顆splay,沒(méi)有快速的方法,把size小的子樹(shù)里的節(jié)點(diǎn)一個(gè)一個(gè)塞到大樹(shù)中。記得這個(gè)思想MS是09年一場(chǎng)網(wǎng)絡(luò)賽里有過(guò)的,不過(guò)那題的詢(xún)問(wèn)很簡(jiǎn)單,恩
            代碼
            # include <cstdio>
            # include <utility>
            # include <functional>
            # include <cstdlib>
            # include <vector>
            using namespace
            std;
            struct
            node
            {

                int
            sz;
                pair<int,int> val;
                node *l,*r,*pre;
                void
            clear()
                {

                    l=r=pre=NULL;
                }
            }
            buff[20005];
            inline
            bool cmp(const pair<int,int> &a,const pair<int,int> &b)
            {

                if
            (a.first!=b.first) return a.first<b.first;
                else return
            a.second<b.second;
            }

            inline
            void update(node *pos)
            {

                pos->sz=(pos->l?(pos->l->sz):0)+(pos->r?(pos->r->sz):0)+1;
            }

            void
            zig(node *pos)
            {

                node *gf=pos->pre->pre,*f=pos->pre;
                (
            f->l)=(pos->r);
                if
            (pos->r) (pos->r->pre)=f;
                update(f);
                (
            pos->r)=f;
                (
            f->pre)=pos;
                (
            pos->pre)=gf;
                if
            (gf&&(gf->l)==f) gf->l=pos;
                else if
            (gf&&(gf->r)==f) (gf->r)=pos;
            }

            void
            zag(node *pos)
            {

                node *gf=pos->pre->pre,*f=pos->pre;
                (
            f->r)=(pos->l);
                if
            (pos->l) (pos->l->pre)=f;
                update(f);
                f->pre=pos;
                pos->l=f;
                pos->pre=gf;
                if
            (gf&&gf->l==f) (gf->l)=pos;
                else if
            (gf&&gf->r==f) (gf->r)=pos;
            }

            void
            spaly(node *pos)
            {

                while
            (pos->pre)
                {

                    if
            (pos->pre->pre==NULL)
                        if
            (pos==(pos->pre->l)) zig(pos);
                        else
            zag(pos);
                    else

                    {

                        node *t=pos->pre->pre;
                        if
            (t->l&&pos==(t->l->l))
                            zig(pos->pre),zig(pos);
                        else if
            (t->r&&pos==(t->r->r))
                            zag(pos->pre),zag(pos);
                        else if
            (t->l&&pos==(t->l->r))
                            zag(pos),zig(pos);
                        else

                        {

                            zig(pos);
                            zag(pos);
                        }
                    }
                }

                update(pos);
            }

            void
            sub_insert(node *p1,node *p2)
            {

                node *pre;
                spaly(p2);
                while
            (p2)
                {

                    pre=p2;
                    if
            (cmp(p1->val,p2->val)) p2=p2->l;
                    else
            p2=p2->r;
                }

                if
            (cmp(p1->val,pre->val))
                    pre->l=p1,p1->pre=pre,spaly(p1);
                else

                    pre->r=p1,p1->pre=pre,spaly(p1);
            }

            void
            ins(node *p1,node *p2)
            {

                if
            (p1->l) ins(p1->l,p2);
                if
            (p1->r) ins(p1->r,p2);
                p1->l=p1->r=p1->pre=NULL;
                p1->sz=1;
                sub_insert(p1,p2);
            }

            void
            insert(node *p1,node *p2)
            {

                spaly(p1),spaly(p2);
                if
            (p1->sz<p2->sz)
                    ins(p1,p2);
                else
            ins(p2,p1);
            }

            int
            select(int pos,int k)
            {

                node *p=buff+pos;
                spaly(p);
                if
            (k>(p->sz)||k<1) return 0;
                else
            k=(p->sz)+1-k;
                int
            co=0;
                while
            (true)
                {

                    if
            (co++>500000) exit(0);
                    if
            ((p->l?p->l->sz:0)>=k) p=p->l;
                    else if
            ((p->l?p->l->sz:0)+1==k)
                       break
            ;
                    else
            k-=(p->l?(p->l->sz):0)+1,p=p->r;
                }

                 spaly(p);
                 return
            p->val.first;
            }

            void
            change(pair<int,int> val)
            {

                node *p=buff+val.second;
                spaly(p);
                p->val=val;
                if
            (p->l&&p->r)
                {

                    node *t1=(p->l),*t2=(p->r);
                    (
            t1->pre)=(t2->pre)=(p->l)=(p->r)=NULL;
                    while
            (t1->r) t1=t1->r;
                    spaly(t1);
                    (
            t1->r)=t2;
                    (
            t2->pre)=t1;
                    spaly(t2);
                    insert(t2,p);
                }

                else if
            (p->l)
                {

                    node *t=p->l;
                    (
            p->l)=(t->pre)=NULL;
                    insert(t,p);
                }

                else if
            (p->r)
                {

                    node *t=p->r;
                    (
            p->r)=(t->pre)=NULL;
                    insert(t,p);
                }

            }

            int
            n,m;
            pair<int,int> edge[60005];
            bool
            used[60005];
            int
            father[20005];
            pair<int,pair<int,int> >  ask[1000005];
            int
            co=0;
            int
            find(int pos)
            {

                if
            (father[pos]==pos) return pos;
                else return
            father[pos]=find(father[pos]);
            }

            int
            main()
            {

                int
            test=1;
                while
            (scanf("%d%d",&n,&m)!=EOF&&(n||m))
                {

                    for
            (int i=1;i<=n;i++)
                    {

                        buff[i].clear();
                        buff[i].val.second=i;
                        father[i]=i;
                        scanf("%d",&buff[i].val.first);
                    }

                    for
            (int i=1;i<=m;i++)
                    {

                        used[i]=true;
                        scanf("%d%d",&edge[i].first,&edge[i].second);
                    }

                    char
            type[5];
                    int
            number=0;
                    co=0;
                    while
            (scanf("%s",type)&&*type!='E')
                    {

                        pair<int,pair<int,int> > tmp;
                        switch
            (*type)
                        {

                        case
            'D':
                            tmp.first=2;
                            scanf("%d",&tmp.second.first);
                            used[tmp.second.first]=false;
                            break
            ;
                        case
            'C':
                        {

                            tmp.first=1;
                            scanf("%d%d",&tmp.second.second,&tmp.second.first);
                            int
            tt=buff[tmp.second.second].val.first;
                            buff[tmp.second.second].val=tmp.second;
                            tmp.second.first=tt;
                            break
            ;
                        }

                        case
            'Q':
                            tmp.first=0;
                            number++;
                            scanf("%d%d",&tmp.second.first,&tmp.second.second);
                            break
            ;
                        };

                        ask[co++]=tmp;
                    }

                    for
            (int i=1;i<=m;i++)
                        if
            (used[i]&&find(edge[i].first)!=find(edge[i].second))
                            insert(buff+edge[i].first,buff+edge[i].second),father[find(edge[i].first)]=find(edge[i].second);

                       
                    double
            total=0;
                    for
            (int i=co-1;i>=0;i--)
                    {

                        switch
            (ask[i].first)
                        {

                        case
            0:
                            total+=select(ask[i].second.first,ask[i].second.second);
                            break
            ;
                        case
            1:
                            change(ask[i].second);
                            break
            ;
                        case
            2:
                            //break;
                            if(find(edge[ask[i].second.first].first)!=find(edge[ask[i].second.first].second))
                            insert(buff+edge[ask[i].second.first].first,buff+edge[ask[i].second.first].second),
                            father[find(edge[ask[i].second.first].first)]=find(edge[ask[i].second.first].second);
                            break
            ;
                        };
                    }

                    printf("Case %d: %.6f\n",test++,number?total/number:0);

                }

                return
            0;
            }

            posted on 2011-09-30 08:51 yzhw 閱讀(497) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): data struct

            <2025年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            導(dǎo)航

            統(tǒng)計(jì)

            公告

            統(tǒng)計(jì)系統(tǒng)

            留言簿(1)

            隨筆分類(lèi)(227)

            文章分類(lèi)(2)

            OJ

            最新隨筆

            搜索

            積分與排名

            最新評(píng)論

            閱讀排行榜

            久久婷婷五月综合国产尤物app | 91精品国产色综久久| 国产精品欧美久久久天天影视| 久久午夜无码鲁丝片| 精品久久国产一区二区三区香蕉| 久久久精品视频免费观看| 亚洲伊人久久精品影院| 草草久久久无码国产专区| 久久人做人爽一区二区三区| 国产99久久精品一区二区| 国内精品伊人久久久影院| 狠狠人妻久久久久久综合| 亚洲AV无码1区2区久久| 久久成人小视频| 久久影院久久香蕉国产线看观看| 久久天天躁狠狠躁夜夜网站| 久久免费视频一区| 国产精品久久久天天影视香蕉| 99久久精品免费| 久久精品国产福利国产琪琪| 国产精品久久久久aaaa| 狠狠色综合网站久久久久久久高清| av午夜福利一片免费看久久| 中文国产成人精品久久亚洲精品AⅤ无码精品 | AV狠狠色丁香婷婷综合久久 | 久久精品国产2020| 亚洲另类欧美综合久久图片区| 国产精品亚洲综合专区片高清久久久| 久久综合给合久久狠狠狠97色| 99久久精品九九亚洲精品| 91精品国产91久久久久久青草| 成人综合伊人五月婷久久| 狠狠色丁香婷婷久久综合不卡 | 亚洲七七久久精品中文国产| 久久国产一区二区| 99久久99久久精品国产| 国产精品免费看久久久香蕉| 久久精品国产国产精品四凭 | 精品久久人妻av中文字幕| 久久久久久久久无码精品亚洲日韩 | 99久久久精品免费观看国产|