#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#define space putchar(' ')
#define enter putchar('\n')
using namespace std;
typedef long long ll;
template <class T>
void read(T &x){
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
    if(c == '-') op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
    x = x * 10 + c - '0';
    if(op) x = -x;
}
template <class T>
void write(T x){
    if(x < 0) putchar('-'), x = -x;
    if(x >= 10) write(x / 10);
    putchar('0' + x % 10);
}

typedef long double ldb;
const int N = 300005;
int n, m;
struct node {
    node *fa, *ch[2];
    int val, sum;
    bool rev;
    node(){
    fa = ch[0] = ch[1] = NULL;
    val = sum = 0;
    rev = 0;
    }
    bool which(){
    return fa->ch[1] == this;
    }
    bool isroot(){
    return fa == NULL || (fa->ch[0] != this && fa->ch[1] != this);
    }
    void upt(){
    sum = val;
    if(ch[0] != NULL) sum ^= ch[0]->sum;
    if(ch[1] != NULL) sum ^= ch[1]->sum;
    }
    void pushdown(){
    if(!rev) return;
    swap(ch[0], ch[1]);
    if(ch[0] != NULL) ch[0]->rev ^= 1;
    if(ch[1] != NULL) ch[1]->rev ^= 1;
    rev = 0;
    }
} s[N];

void rotate(node *u){
    node *v = u->fa, *w = v->fa, *b = u->ch[!u->which()];
    if(!v->isroot()) w->ch[v->which()] = u;
    u->which() ? (u->ch[0] = v, v->ch[1] = b) : (u->ch[1] = v, v->ch[0] = b);
    u->fa = w, v->fa = u;
    if(b != NULL) b->fa = v;
    v->upt();
}
void splay(node *u){
    static node *stk[N];
    int top;
    stk[top = 1] = u;
    while(!stk[top]->isroot()) stk[top + 1] = stk[top]->fa, top++;
    while(top) stk[top--]->pushdown();
    while(!u->isroot()){
    if(!u->fa->isroot()){
        if(u->which() == u->fa->which()) rotate(u->fa);
        else rotate(u);
    }
    rotate(u);
    }
    u->upt();
}
void access(node *u){
    node *v = NULL;
    while(u != NULL){
    splay(u);
    u->ch[1] = v;
    u->upt();
    v = u;
    u = u->fa;
    }
}
void makeroot(node *u){
    access(u);
    splay(u);
    u->rev ^= 1;
}
node *findroot(node *u){
    access(u);
    splay(u);
    while(u->pushdown(), u->ch[0] != NULL)
    u = u->ch[0];
    splay(u);
    return u;
}
void link(node *u, node *v){
    if(findroot(u) == findroot(v)) return;
    makeroot(v);
    v->fa = u;
}
void cut(node *u, node *v){
    makeroot(u);
    access(v);
    splay(v);
    if(v->ch[0] == u)
    v->ch[0] = u->fa = NULL;
}
int query(node *u, node *v){
    makeroot(u);
    access(v);
    splay(v);
    return v->sum;
}
void change(node *u, int x){
    splay(u);
    u->val = x;
    u->upt();
}

int main(){

    read(n), read(m);
    for(int i = 1; i <= n; i++)
    read(s[i].val), s[i].upt();
    int op, x, y;
    while(m--){
    read(op), read(x), read(y);
    if(op == 0) write(query(s + x, s + y)), enter;
    else if(op == 1) link(s + x, s + y);
    else if(op == 2) cut(s + x, s + y);
    else change(s + x, y);
    }

    return 0;
}

然而时隔多年,我也终于写出了自己的SPLAY指针板

写完过后突然发现也不是很难,只是要特别注意zero的调用

这是洛谷的P4146 系列终结者

// luogu-judger-enable-o2
#include<bits/stdc++.h>
using namespace std;
struct node
{
    node *son[2],*father;
    int maxa,tag,num,flag,size;
}pool[1000005],*tail=pool,*root,*zero;
int n,m,shu1,shu2,shu3,shu4;
void update(node *nd)
{
    nd->size=nd->son[0]->size+nd->son[1]->size+1;
    if(nd->son[0]!=zero&&nd->son[1]!=zero)
    nd->maxa=max(nd->num,max(nd->son[0]->maxa,nd->son[1]->maxa));
    else if(nd->son[0]!=zero)
    nd->maxa=max(nd->num,nd->son[0]->maxa);
    else if(nd->son[1]!=zero)
    nd->maxa=max(nd->num,nd->son[1]->maxa);
    else nd->maxa=nd->num;
}
void pushdown(node *nd)
{
    if(nd->flag)
    {
        swap(nd->son[0],nd->son[1]);
        if(nd->son[0]!=zero)
        nd->son[0]->flag^=1;
        if(nd->son[1]!=zero)
        nd->son[1]->flag^=1;
        nd->flag=0;
    }
    if(nd->tag)
    {
        if(nd->son[0]!=zero)
        {
            nd->son[0]->maxa+=nd->tag;
            nd->son[0]->num+=nd->tag;
            nd->son[0]->tag+=nd->tag;
        }
        if(nd->son[1]!=zero)
        {
            nd->son[1]->maxa+=nd->tag;
            nd->son[1]->num+=nd->tag;
            nd->son[1]->tag+=nd->tag;
        }
        nd->tag=0;
    }
}
void init()
{
    zero=tail++;
    zero->son[0]=zero->son[1]=zero->father=zero;
    zero->num=zero->maxa=zero->size=zero->tag=0;
}
node *build(int l,int r)
{
    if(l>r) return zero;
    node *nd=tail++;
    nd->maxa=nd->num=0;
    int mid=(l+r)>>1;
    nd->son[0]=build(l,mid-1);
    nd->son[1]=build(mid+1,r);
    if(nd->son[0]!=zero)
    nd->son[0]->father=nd;
    if(nd->son[1]!=zero)
    nd->son[1]->father=nd;
    update(nd);
    return nd;
}
node *find(int x)
{
    node *now=root;
    while(1)
    {
        pushdown(now);
        if(now->son[0]->size>=x) now=now->son[0];
        else if(now->son[0]->size+1==x) return now;
        else x-=now->son[0]->size+1,now=now->son[1];
    }
}
void rotate(node *nd)
{
    node *p=nd->father;
    node *pp=p->father;
    int another=pp->son[1]==p;
    int kind=(p->son[0]==nd);
    node *s=nd->son[kind];
    if(s!=zero)
    s->father=p;
    p->son[!kind]=s;
    if(pp!=zero)
    nd->father=pp;
    else root=nd,nd->father=zero;
    if(pp!=zero)
    pp->son[another]=nd;
    nd->son[kind]=p;
    p->father=nd;
    update(p);
    update(nd);
}
void splay(node *nd,node *pre)
{
    while(nd->father!=pre)
    {
        node *p=nd->father;
        if(p->father==pre)
        {
            rotate(nd);
            break;
        }
        node *pp=p->father;
        if((pp->son[1]==p)==(p->son[1]==nd))
        {
            rotate(p);
            rotate(nd);
        }
        else 
        {
            rotate(nd);
            rotate(nd);
        }
    }
}
void modify(int l,int r,int delta)
{
    node *r1=find(l);
    node *r2=find(r+2);
    splay(r1,zero);
    splay(r2,r1);
    r2->son[0]->tag+=delta;
    r2->son[0]->num+=delta;
    r2->son[0]->maxa+=delta;
}
void reverse(int l,int r)
{
    node *r1=find(l);
    node *r2=find(r+2);
    splay(r1,zero);
    splay(r2,r1);
    r2->son[0]->flag^=1;
}
int query(int l,int r)
{
    node *r1=find(l);
    node *r2=find(r+2);
    splay(r1,zero);
    splay(r2,r1);
    return r2->son[0]->maxa;
}
int main()
{
    cin>>n>>m;
    init();
    root=build(1,n+2);
    root->father=zero;
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&shu1);
        if(shu1==1)
        {
            scanf("%d%d%d",&shu2,&shu3,&shu4);
            modify(shu2,shu3,shu4);
        }
        else if(shu1==2)
        { 
            scanf("%d%d",&shu2,&shu3);
            reverse(shu2,shu3);
        }
        else 
        {
            scanf("%d%d",&shu2,&shu3);
            printf("%d\n",query(shu2,shu3));
        }
    }
    return 0;
}