poj 3468 splay入門

存個模板。從其它地方改過來的。。
區間修改,區間查詢

#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int MAXN = 50010;
struct Node *null;
struct Node{
    Node *ch[2], *fa;
    int size;
    ll lazy, sum, key;
    inline void update_add(ll val){
       lazy += val;
       sum += val * size;
       key += val;
    }
    inline void setc(Node *p, int d){
        ch[d] = p;
        p->fa = this;
    }
    inline bool d(){
        return fa->ch[1] == this;
    }
    inline void push_up(){
        size = ch[0]->size+ch[1]->size+1;
        sum = ch[0]->sum + ch[1]->sum + key;
    }
    inline void push_down(){
        if(lazy){
            ch[0]->update_add(lazy);
            ch[1]->update_add(lazy);
            lazy = 0;
        }
    }
    void clear(int _key){
        size = 1;
        sum = key = _key;
        ch[0] = ch[1] = fa = null;
        lazy = 0;
    }
};
Node pool[MAXN * 15], *tail;
Node *bc[MAXN];
int bc_top;
void init(){
    tail = pool;
    bc_top = 0;
    null = tail++;
    null->size  = 0;
    null->ch[0] = null->ch[1] = null->fa = null;
}
inline void rotate(Node *x){
    Node *f = x->fa, *ff = x->fa->fa;
    int c = x->d(), cc = f->d();
    f->setc(x->ch[!c], c);
    x->setc(f, !c);
    if (ff->ch[cc] == f)ff->setc(x, cc);
    else x->fa = ff;
    f->push_up();
}
void go(Node *x, Node *goal){
    if(x != goal) go(x->fa, goal);
    x->push_down();
}
inline void splay(Node* &root, Node* x, Node* goal){
    go(x, goal);
    while (x->fa != goal){
        if (x->fa->fa == goal)rotate(x);
        else {
            bool f = x->fa->d();
            x->d() == f ? rotate(x->fa) : rotate(x);
            rotate(x);
        }
    }
    x->push_up();
    if (goal == null)root = x;
}
Node* newNode(int key){
    Node* p;
    if (bc_top)p = bc[--bc_top];
    else p = tail++;
    p->clear(key);
    return p;
}
Node* get_kth(Node* x, int k){
    x->push_down();
    Node*u = x;
    while (u->ch[0]->size+1 != k)
    {
        if (u->ch[0]->size >= k)
            u = u->ch[0];
        else {
            k -= u->ch[0]->size + 1;
            u = u->ch[1];
        }
        u->push_down();
    }
    return u;
}
Node* build(int l, int r, int *a){
    if (l > r)return null;
    int mid = (l + r) >> 1;
    Node* u = newNode(a[mid]);
    u->setc(build(l, mid - 1, a), 0);
    u->setc(build(mid + 1, r, a), 1);
    u->push_up();
    return u;
}
int n, q;
int a[N];
int main(){
    while (cin >> n >> q){
        for (int i = 1; i <= n; i++)scanf("%d",a+i);
        init();
        Node* root = build(0, n + 1, a);
        Node* lnode,* rnode, *tmp;
        char str[2];
        while (q--){
            int l, r; ll val;
            scanf("%s", str); scanf("%d %d", &l, &r);
            lnode = get_kth(root, l);
            rnode = get_kth(root, r+2);
            splay(root, lnode, null);
            splay(root, rnode, lnode);
            if (str[0] == 'Q')
                printf("%lld\n", root->ch[1]->ch[0]->sum);
            else {
                scanf("%lld", &val);
                tmp = root->ch[1]->ch[0];
                tmp->update_add(val);
                root->ch[1]->push_up(); 
                root->push_up();
            } 
        }
    }
    return 0;
}
發佈了58 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章