Old Driver Tree(ODT,老驱动树)的初级使用

来源:互联网 发布:手机电影特效制作软件 编辑:程序博客网 时间:2024/06/06 10:02

以前一直听说过一种神奇的数据结构ODT能够水过无数数据结构题,苦于找不到相关的学习资料。在打了CF#449 Div.1 之后,发现这其实是一个很智障的东西。写一点东西以后复习吧。。


ODT操作前提

一般用ODT的题有两个操作要求:
1.有区间覆盖操作,即是把[l,r]区间全部覆盖为x.
2.数据随机

看到2大概各位dalao应该已经懂了这个算法是有多么的不稳定了。不过随机情况下的效率确实挺高。


ODT工作原理

ODT其实就是把相同的区间整合到1个节点提高访问速度(比如区间覆盖)。所以随便写一颗平衡树即可。下面来看两道例题:


应用

ODT写起来数据结构是真的短。。

Codeforces#449 Div.1 C

维护一种数据结构,支持:
区间加,区间覆盖,区间求第k大,区间求x次方和(x1e9)
保证数据随机。

貌似就是要告诉你一定要用ODT。。
如果谁写出了一种维护x次方和的高效数据结构请教教我。
证明时间复杂度请看:http://codeforces.com/blog/entry/56135
代码里面也有。

BZOJ3337
貌似这道题ODT吊打块状链表??无论是代码还是速度都很领先啊。。

#include<bits/stdc++.h>typedef long long ll;typedef unsigned int ut;using namespace std;inline void W(ll x){    static int buf[50];    if(!x){putchar('0');return;}    if(x<0){putchar('-');x=-x;}    while(x){buf[++buf[0]]=x%10;x/=10;}    while(buf[0])putchar(buf[buf[0]--]+'0');}inline ut unit(){    static ut state0=19491001;    state0^=(state0<<13);    state0^=(state0>>17);    state0^=(state0<<5);    return state0; }inline int rd(){    char ch=getchar();int i=0,f=1;    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}    while(isdigit(ch)){i=(i<<1)+(i<<3)+ch-'0';ch=getchar();}    return i*f;} const int Maxn=5e5+50;const ll INF=0x3f3f3f3f;int n,Q;struct node{    node *lc,*rc;    bool rev_tag;    ll add_tag;    ll val,sum,mx,mn;    int sze,cnt;    ut pri;    inline void pd();    inline void add(int v);    inline void rev();    inline void upt(); }Pool[Maxn],*pool=Pool,*null=Pool,*rt=null;typedef pair<node*,node*> pii;inline node* newnode(int val,int o){    ++pool;pool->lc=pool->rc=null;    pool->rev_tag=(pool->add_tag=0);    pool->val=val;pool->sum=1ll*val*o;    pool->mx=val;pool->mn=val;    pool->sze=(pool->cnt=o);    pool->pri=unit();    return pool;}inline void node::add(int v){    val+=v;sum+=1ll*v*sze;add_tag+=v;    mx+=v;mn+=v;}inline void node::rev(){    swap(lc,rc);rev_tag=(!rev_tag);}inline void node::upt(){    sum=lc->sum+rc->sum+1ll*val*cnt;    sze=lc->sze+rc->sze+cnt;    mx=max(val,max(lc->mx,rc->mx));    mn=min(val,min(lc->mn,rc->mn));} inline void node::pd(){    if(add_tag){        if(lc!=null)lc->add(add_tag);        if(rc!=null)rc->add(add_tag);        add_tag=0;     }    if(rev_tag){        if(lc!=null)lc->rev();        if(rc!=null)rc->rev();        rev_tag=0;    }}inline pii split(node *x,int sze){    if(x==null)return make_pair(null,null);    x->pd();    if(x->lc->sze+x->cnt<=sze){        pii tr1=split(x->rc,sze-x->lc->sze-x->cnt);        x->rc=tr1.first;x->upt();        return make_pair(x,tr1.second);    }else{        pii tr1=split(x->lc,sze);        x->lc=tr1.second;x->upt();        return make_pair(tr1.first,x);    }}inline node* merge(node *x,node *y){    if(x==null)return y;    if(y==null)return x;    x->pd();y->pd();    if(x->pri>y->pri){        x->rc=merge(x->rc,y);        x->upt();return x;    }else {        y->lc=merge(x,y->lc);        y->upt();return y;    }}inline int findlef(node *x,int rdc){    if(x->lc!=null){        int t=findlef(x->lc,rdc);        x->upt();return t;    }else{        x->cnt-=rdc;x->upt();        return x->val;    }}inline pii Get(node *x,int sze){    pii tr1=split(x,sze);    int sz=sze-tr1.first->sze;    if(sz){        int t=findlef(tr1.second,sz);        tr1.first=merge(tr1.first,newnode(t,sz));    }    return tr1;}vector< pair<ll,int> >vv;inline void getnode(node *x){    vv.push_back(make_pair(x->val,x->cnt));    x->pd();    if(x->lc!=null)getnode(x->lc);    if(x->rc!=null)getnode(x->rc);}inline void travel(node *x){    vv.clear();    getnode(x);}int main(){    n=rd();null->mx=-INF;null->mn=INF;    for(int i=1;i<=n;i++){rt=merge(rt,newnode(rd(),1));}    Q=rd();while(Q--){        int op=rd();        switch(op){            case 1:{                int x=rd(),val=rd();                pii tr1=Get(rt,x);                rt=merge(tr1.first,merge(newnode(val,1),tr1.second));                break;            }            case 2:{                int x=rd();                pii tr1=Get(rt,x-1);                pii tr2=Get(tr1.second,1);                rt=merge(tr1.first,tr2.second);                break;            }            case 3:{                int x=rd(),y=rd();                pii tr1=Get(rt,x-1);                pii tr2=Get(tr1.second,y-x+1);                tr2.first->rev();                rt=merge(tr1.first,merge(tr2.first,tr2.second));                 break;            }            case 4:{                int l=rd(),r=rd(),k=rd(),len=r-l+1;                k%=len;int sz1=len-k;                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,sz1);                pii tr3=Get(tr2.second,k);                rt=merge(merge(tr1.first,tr3.first),merge(tr2.first,tr3.second));                break;            }            case 5:{                int l=rd(),r=rd(),val=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                tr2.first->add(val);                rt=merge(tr1.first,merge(tr2.first,tr2.second));                break;            }             case 6:{                int l=rd(),r=rd(),val=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                rt=merge(tr1.first,merge(newnode(val,r-l+1),tr2.second));                 break;            }            case 7:{                int l=rd(),r=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                W(tr2.first->sum);putchar('\n');                rt=merge(tr1.first,merge(tr2.first,tr2.second));                break;            }            case 8:{                int l=rd(),r=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                W(tr2.first->mx-tr2.first->mn);putchar('\n');                rt=merge(tr1.first,merge(tr2.first,tr2.second));                break;            }            case 9:{                int l=rd(),r=rd(),val=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                travel(tr2.first);                ll ans=INF;                for(int t=vv.size()-1;t>=0;t--){                    ans=min(ans,abs(val-vv[t].first));                }                W(ans);putchar('\n');                rt=merge(tr1.first,merge(tr2.first,tr2.second));                break;            }            case 10:{                int l=rd(),r=rd(),k=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                travel(tr2.first);                sort(vv.begin(),vv.end());int pos=0;                while(1){                    k-=vv[pos].second;                    if(k<=0){W(vv[pos].first);putchar('\n');break;}                    ++pos;                }                rt=merge(tr1.first,merge(tr2.first,tr2.second));                break;            }            case 11:{                int l=rd(),r=rd(),val=rd();                pii tr1=Get(rt,l-1);                pii tr2=Get(tr1.second,r-l+1);                travel(tr2.first);int cnt=0;                for(int t=vv.size()-1;t>=0;t--){                    if(vv[t].first<val)cnt+=vv[t].second;                }                W(cnt);putchar('\n');                rt=merge(tr1.first,merge(tr2.first,tr2.second));                break;            }        }     }}
阅读全文
0 0
原创粉丝点击