The first knowledge of splay tree (Hihocoder #1034: The problem of the destroyer)

Source: Internet
Author: User
Tags time interval
Topic Connection Title Description

time limit: 10000ms
single point time limit: 1000ms
memory limit: 256MB



Problem Solving Ideas:

The direct violence at each point in time is obviously the tle, and now it is not considered at the point of time, but in what time points each unit of magic is extracted, so that each unit has a set of time intervals to be drawn, and each magic unit has a maximum of M and a recovery speed R, Consider a set of time intervals for a magic unit A, sorted by size: greater than or equal to (m+r-1)/R: means that the mana extracted is the mana limit M, and if there is a k time interval to satisfy the condition, the sum of the magical values extracted by this part is k*m. less than (m+r-1)/R: sum multiplied by R is the total mana extracted from that part. The sum of the total mana extracted from these two parts is the total mana extracted by a mana unit. All units of magic are so considered and summed up.

The key here is how to maintain these intervals, first of all to maintain the point at which each magic unit has been extracted, and then to maintain the interval based on these points in time.

Point-in- time maintenance : Using a stretch tree a, for each of the Magic unit 1-n I, the operation time to start interval I into the extension tree A, a maintenance process to ensure the order of time , in fact, is a binary sorting tree, After the insert is complete, a maintains all points of time for the extraction operation of the Magic Unit I.
If, at the same time as inserting a point B, the first and subsequent C of the sequence traversal of the point is taken, it means that for the time interval of I and the subsequent magic units , there is a decrease: c-a, which adds two: B-a and C-b.
and after the extraction and settlement of the Magic Unit I , remove all the operation point B from a to end the interval, also get precursor A and successor C, which means that the time interval of the magic unit after I decreased by two: C-b and B-a, added one: c-a.

time interval maintenance: still using a stretch number b,b maintains the time interval (same order), and maintains additional information, all the time interval sum sums, and the number of all time intervals is size.
For the previous point-in-time maintenance, each a insertion will result in a B delete and two b insertions;
Also every a delete, will result in two B deletions and a B insertion. Code:

#include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <set> #
Include <cmath> #include <algorithm> using namespace std;
#define MAXN 500005 typedef long Long int ll64;
typedef unsigned long long int ll65;

Const LL65 INFT = (1e9) + 1; typedef struct ope{ll65 s, M, R;}
Ope
        typedef struct stree{typedef struct node{struct node *ch[2], *pre;
    LL65 tmseg, size, num, sums;
    }node;
    Node buf[maxn*2], *root, *nil;
    int bufsize;
        Node *getnode (ll65 tmseg, node* fa) {node *p = NULL;
        if (bufsize<maxn*2) {p = buf + bufsize++;}
        else{p = (node*) malloc (sizeof (node));}
        P->ch[0] = p->ch[1] = nil;
        p->tmseg = P->sums = tmseg;
        P->pre = FA;
        P->size = P->num = 1;
    return p;
        } inline int Update (node *x) {if (x->num<0) x->num=0; X->size=x->ch[0]->size+x->ch[1]->size+x->num;
        x->sums=x->ch[0]->sums+x->ch[1]->sums+x->num*x->tmseg;
    return 0;
        } int init () {bufsize = 0;
        Nil = getnode (0, NULL);
        Nil->ch[0] = nil->ch[1] = NULL;
        nil->size = Nil->num = 0;
        root = getnode (0, nil);
        ROOT-&GT;CH[1] = GetNode (Inft, Root);
        Update (root);
    return 0;
        } int Rotateto (node *x, int to) {Node *XF = x->pre;
        xf->ch[to ^ 1] = x->ch[to];
        xf->ch[to ^ 1]->pre = XF;
        X->pre = xf->pre;
        if (xf->pre->ch[0] = = XF) x->pre->ch[0] = x;
        else x->pre->ch[1] = x; Xf->pre = x;
        X->ch[to] = XF;
        Update (XF);
        if (xf==root) root=x;
    return 0;
                } int splay (node *x, node *fa) {while (x->pre! = FA) {if (X->pre->pre = = FA) {
                if (x->pre->ch[0] = = x) rotateto (x, 1); else Rotateto (x, 0); } else{if (x->pre->pre->ch[0] = = X->pre) {if (x->pre->c
                    H[0] = = x) {Rotateto (x->pre, 1); Rotateto (x, 1);}
                else {rotateto (x, 0); Rotateto (x, 1);}
                    } else{if (x->pre->ch[0] = = x) {Rotateto (x, 1); Rotateto (x, 0);}
                else {rotateto (x->pre, 0); Rotateto (x, 0);}
        }}} update (x);
    return 0;
        } int Select (ll65 value,ll65 &size1,ll65 &size2) {node *p = root,*q=null;
            while (P! = nil) {if (p->tmseg = = value) break;
            else if (P->tmseg > value) {q = p; p = p->ch[0];}
        else {q = p; p = p->ch[1];}
            } if (p = = nil) {splay (q, nil);
                if (Q->tmseg < value) {p=root->ch[1]; while (P->ch[0]!=nil) {p=p->ch[0];}
            Splay (P, nil);
        }}else{splay (P, nil);
        } size1 = root->ch[0]->sums;
        Size2 = root->size-root->ch[0]->size-1;
    return 0;
        } int Insert (LL65 value) {node *p = root, *q = NULL;
        if (value==0) return 0;
            while (P! = nil) {if (p->tmseg = = value) break;
            else if (P->tmseg > value) {q = p; p = p->ch[0];}
        else {q = p; p = p->ch[1];}
            if (P! = nil) {p->num + = 1;
            P->size + = 1;
            P->sums + = value;
        Splay (P, nil);
            } else{p = getnode (value, q);
            if (value<q->tmseg) q->ch[0] = p;
            else q->ch[1] = p;
        Splay (P, nil);
    } return 0;
        } int Remove (ll65 value) {node *p = root, *q = NULL;
        if (value==0) return 0; while (P! = nil) {if (p->tmseg = = value) break;
            else if (P->tmseg > value) {q = p; p = p->ch[0];}
        else {q = p; p = p->ch[1];}
            } if (P! = nil) {p->num-= 1;
            P->size-= 1;
            P->sums-= value;
        Splay (P, nil);
    } return 0;

}}stree;
        typedef struct stree1{typedef struct node{struct node *pre, *ch[2];
    LL65 TM;
    }node;
    Node Buf[maxn*4], *root, *nil;
    int bufsize;
        Node *getnode (ll65 Value, node *fa) {node *p = NULL;
        if (bufsize<maxn*4) p = buf + bufsize++;
        else P = (node*) malloc (sizeof (node)); P->pre = FA;
        P->tm = value;
        P->ch[0] = p->ch[1] = nil;
    return p;
        } int init () {bufsize = 0;
        nil = NULL;
        Nil = getnode (0, NULL);
        Nil->ch[0] = nil->ch[1] = NULL;
        NIL-&GT;TM = 0;
        root = getnode (0, nil); ROOT-&GT;CH[1] = GetNode (inFT, Root);
    return 0;
        } int Rotateto (node *x, int to) {Node *XF = x->pre;
        xf->ch[to ^ 1] = x->ch[to];
        xf->ch[to ^ 1]->pre = XF;
        X->pre = xf->pre;
        if (xf->pre->ch[0] = = XF) x->pre->ch[0] = x;
        else x->pre->ch[1] = x; Xf->pre = x;
        X->ch[to] = XF;
        if (xf==root) root=x;
    return 0;
                } int splay (node *x, node *fa) {while (x->pre! = FA) {if (X->pre->pre = = FA) {
                if (x->pre->ch[0] = = x) rotateto (x, 1);
            else Rotateto (x, 0); } else{if (x->pre->pre->ch[0] = = X->pre) {if (x->pre->c
                    H[0] = = x) {Rotateto (x->pre, 1); Rotateto (x, 1);}
                else {rotateto (x, 0); Rotateto (x, 1);}
     } else{if (x->pre->ch[0] = = x) {Rotateto (x, 1); Rotateto (x, 0);}               else {rotateto (x->pre, 0); Rotateto (x, 0);}
    }}} return 0;
        } int Insert (LL65 TM, Ll65 &a, ll65 &b, ll65 &c) {node *p = root, *q = NULL;
        if (tm==0) return 0;
            while (P! = nil) {if (P->tm = = tm) break;
            else if (P->tm > tm) {q = p; p = p->ch[0];}
        else {q = p; p = p->ch[1];}
            } if (p = = nil) {P=getnode (tm,q);
            if (tm > Q->tm) {q->ch[1]=p;
            }else q->ch[0]=p; Splay (P, nil);
            B=tm; p=root->ch[0];
            while (P->ch[1]!=nil) p=p->ch[1];
            a=p->tm; p=root->ch[1];
            while (P->ch[0]!=nil) p=p->ch[0];
            c=p->tm;
        return 1;
        } else return 0;
    return 0;
        } int Remove (LL65 TM, Ll65 &a, ll65 &b, ll65 &c) {node *p = root, *q = NULL; If(tm==0) return 0;
            while (P! = nil) {if (P->tm = = tm) break;
            else if (P->tm > tm) {q = p; p = p->ch[0];}
        else {q = p; p = p->ch[1];}
            } if (P! = nil) {splay (P, nil);
            Node *P1 = p->ch[0];
            while (p1->ch[1]! = nil) P1 = p1->ch[1];
            Node *P2 = p->ch[1];
            while (p2->ch[0]! = nil) P2 = p2->ch[0]; Splay (P1, nil);
            Splay (P2, root); A = p1->tm; b = TM;
            c = p2->tm;
            P2->ch[0] = nil;
        return 1;
        } else return 0;
    return 0;
        } int getmin () {node *p = root, *q = root;
        while (p->ch[0]!=nil) {p = p->ch[0];
        } if (P->ch[1]==nil) {q=p->pre;
            }else{q=p->ch[1];
        while (Q->ch[0]!=nil) q=q->ch[0];
    } return q->tm;

}}stree1; Vector<ll65> Stm[maXN], ETM[MAXN];

Ope OP[MAXN],OPR[MAXN];
    int oprcmp (const ope &a,const ope &b) {if (a.m. = = B.M) return a.r<b.r;
Return a.m<b.m;
    } int main () {ll65 I, j, K;
    Ll65 N, M, L, R, T;
    Freopen ("In.txt", "R", stdin);
    Freopen ("OUT.txt", "w", stdout);
    scanf ("%llu", &n);
    for (i = 1; I <= n; i++) {scanf ("%llu%llu%llu", &op[i].s, &AMP;OP[I].M, &AMP;OP[I].R);
    } scanf ("%llu", &m); i=0;
    K=1;j=1;
    int flag0=0;
    scanf ("%llu%llu%llu", &opr[i].s, &AMP;OPR[I].M, &AMP;OPR[I].R);
    int tst=0,ted=0;
        for (i =1; i<m; i++) {scanf ("%llu%llu%llu", &opr[j].s, &AMP;OPR[J].M, &AMP;OPR[J].R);
                if (opr[j].s! = opr[j-1].s) {if (TED&GT;TST) {sort (opr+tst,opr+ted+1,oprcmp);
                int ii,jj=tst; for (ii =tst+1;ii<=ted;ii++) {if (opr[ii].m<= opr[jj].r+1) {Opr[jj].r=max
                  (OPR[JJ].R,OPR[II].R);  }else{++JJ;  OPR[JJ]=OPR[II]; }} ++JJ;
                OPR[JJ]=OPR[J];  TST=TED=JJ;
            j=jj+1;
                }else{tst=ted=j;
            j + +;
            }}else{ted=j;
        j + +;
        }} if (TED&GT;TST) {sort (opr+tst,opr+ted+1,oprcmp);
        int II, JJ=TST; for (ii =tst+1;ii<=ted;ii++) {if (opr[ii].m<= opr[jj].r+1) {Opr[jj].r=max (opr[jj].r,opr[i
            I].R);
                }else{++JJ;
            OPR[JJ]=OPR[II];
    }} TED=JJ;
        } for (i=0;i<=ted;i++) {stm[opr[i].m].push_back (OPR[I].S);
    Etm[opr[i].r].push_back (OPR[I].S);
    } stree *t1 = new Stree;
    Stree1*t2 = new Stree1; T1->init ();
    T2->init ();
    Ll65 A, B, C;
    Ll65 ans = 0;
    int ret=0,tmpcnt=0; for (i = 1; I <= N, i++) {for (j = 0; J<stm[i].size (); j + +) {if (stm[i][j]==0) flag0= 1;
            tmpcnt++;
            Ret=t2->insert (Stm[i][j], A, b, c);
            cout<< "Insert:" <<a<< "" <<b<< "" <<c<<endl;
                if (ret==1) {//cout<<a<< "" <<b<< "" <<c<<endl;
                    if (c! = Inft) {t1->remove (c-a);
                T1->insert (C-b);
            } t1->insert (B-A);
        }}//cout<<t1->root->sums<<endl;
                if (tmpcnt>0) if (op[i].m>0) {if (op[i].r>0) {ll65 mint = t2->getmin ();
                if (flag0==1) mint=0;
                LL65 size1, Size2;
                LL65 tmp= (op[i].m + op[i].r-1)/OP[I].R;
                T1->select (TMP, SIZE1, size2);
                if (Mint < tmp) {size1-= mint;
                }else size2--;
Ans + = SIZE1*OP[I].R + size2*op[i].m;
                tmp= (Op[i].m-op[i].s + op[i].r-1)/OP[I].R;
                if (Mint < tmp) {ans + + MINT*OP[I].R + op[i].s;
            } else ans + = op[i].m;
            }else{Ans+=op[i].s;
        }}//cout<< "id =" <<i<< ": ans=" <<ans<<endl;
            for (j = 0; J < Etm[i].size (); j + +) {if (etm[i][j]==0) flag0=0;
            tmpcnt--;
            int Ret=t2->remove (ETM[I][J],A,B,C);
            cout<< "Remove:" <<a<< "<<b<<" "<<c<<endl;
                if (ret) {t1->remove (b-a);
                    if (c! = Inft) {t1->remove (c-b);
                T1->insert (C-A);
    }}}} printf ("%llu\n", ans);
return 0;
 }

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.