Splay基本操作和线段树(指针版)

来源:互联网 发布:语音录入软件 编辑:程序博客网 时间:2024/06/05 16:32

    • splay
    • 线段树

splay

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#include<vector>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;struct point {    int key;    point *lch,*rch,*fa;};void leftrotate(point *x){    point *y=x->fa;    y->rch=x->lch;    if(x->lch!=NULL) x->lch->fa=y;    x->fa=y->fa;    if(y->fa!=NULL) {        if(y->fa->lch==y) y->fa->lch=x;        else y->fa->rch=x;    }    y->fa=x;    x->lch=y;}void rightrotate(point *x){    point *y=x->fa;    y->lch=x->rch;    if(x->rch!=NULL) x->rch->fa=y;    x->fa=y->fa;    if(y->fa!=NULL) {        if(y->fa->lch==y) y->fa->lch=x;        else y->fa->rch=x;    }    y->fa=x;    x->rch=y;}void splay(point *x,point *s){    point *p;    while(x->fa!=NULL) {        p=x->fa;        if(p->fa==NULL) {            if(x==p->lch) rightrotate(x);                          else leftrotate(x);            break;        }        if(p->lch==x) {            if(p==p->fa->lch) {                rightrotate(p);                rightrotate(x);            }            else {                rightrotate(x);                leftrotate(x);            }        }        else {            if(p==p->fa->rch) {                leftrotate(p);                leftrotate(x);            }            else {                leftrotate(x);                rightrotate(x);            }        }       }    s=x;}point* Search(int k,point *s){    point *p;    while(p!=NULL&&p->key!=k) {        if(k<p->key) p=p->lch;        else         p=p->rch;    }    splay(p,s);    return p;}void Insert(int key,point *s){    point *z,*x,*y;    z->fa=z->lch=z->rch=NULL;    z->key=key;    x=z; y=NULL;    while(x!=NULL) {        y=x;        if(z->key<x->key) x=x->lch;        else              x=x->rch;    }    z->fa=y;    if(y==NULL) s=z;    else if(z->key<y->key) y->lch=z;         else              y->rch=z;    splay(z,s);}void del(int x,point *s){    point *p;    p=Search(x,s);    s=join(p->lch,p->rch);}point* maximum(point *s){    point *p;    p=s;    while(p->rch!=NULL) p=p->rch;    splay(p,s);    return p;}point* minimum(point *s){    point *p;    p=s;    while(p->lch!=NULL) p=p->lch;    splay(p,s);    return p;}point* predecessor(int x,point *s){    point *p;    p=Search(x,s);    p=p->lch;    return maximum(p);}point* successor(int x,point *s){    point *p;    p=Search(x,s);    p=p->rch;    return mininum(p);}point* join(point *s1,point *s2){    point *p;    if(s1==NULL) return s2;    if(s2==NULL) return s1;    p=maximum(s1);    p->rch=s2;     return  p;}void split(int x,point *s,point *s1,point *s2){    point *p;    p=Search(x,s);    s1=p->lch;    s2=p->rch;}

线段树

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<cstdlib>#include<queue>#include<vector>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)using namespace std;struct Node {    int l,r,sum,delta;    Node *lch,*rch;}; void build(Node *x,int l,int r) {    x->l=l;     x->r=r;    x->sum=x->delta=0;    if(l<r) {        x->lch=new Node;        x->rch=new Node;        int m=(x->l+x->r)>>1;        build(x->lch,l,m);        build(x->rch,m+1,r);    }    else x->lch=x->rch=NULL;}void updata(Node *x) {    x->lch->sum+=x->delta*(x->r-x->l+1);    x->rch->sum+=x->delta*(x->r-x->l+1);    x->lch->delta+=x->delta;    x->rch->delta+=x->delta;    x->delta=0;}void change(Node *x,int l,int r,int delta){    if(x->l>=l&&x->r<=r) {        x->sum+=(x->r-x->l+1)*delta;        x->delta+=delta;    }    else {        if(x->delta!=0) updata(x);        int m=(x->l+x->r)>>1;        if(l<=m) change(x->lch,l,r,delta);        if(r>m) change(x->rch,l,r,delta);        x->sum=x->lch->sum+x->rch->sum;     }}int query(Node *x,int l,int r){    if(x->l>=l&&x->r<=r) {        return x->sum;    }    else {        if(x->delta!=0) updata(x);        int m=(x->l+x->r)>>1;        int ans=0;        if(l<=m) ans+=query(x->lch,l,r);        if(r>m) ans+=query(x->rch,l,r);        return ans;    }}const int N=500000+10;int a[N],n,m;Node *root;int main(){    scanf("%d%d",&n,&m);    root=new Node;    build(root,1,n);    fo(i,1,n) {        scanf("%d",&a[i]);        change(root,i,i,a[i]);    }    for(int a,b,c,i=1;i<=m;i++) {        scanf("%d%d%d",&a,&b,&c);        if(a==1) change(root,b,b,c);        if(a==2) printf("%d\n",query(root,b,c));    }    return 0;}
原创粉丝点击