求助文艺平衡树
查看原帖
求助文艺平衡树
360930
Jairon314楼主2021/8/26 21:21

感觉写的没有问题啊[可怜],发现自己对于平衡树还是理解太浅了,这份代码连样例都过不了......调了一晚上了,看题解也看不懂......有没有大佬能帮忙看看有没有明显的错误啊

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

#define $int long long

/***************快读***************/

namespace IO {
char buf[1<<21], *p1 = buf, *p2 = buf, buf1[1<<21];
inline char gc () {return p1 == p2 && (p2 = (p1 = buf) + fread (buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;}

#ifndef ONLINE_JUDGE
#endif

#define gc getchar

template<class I>
inline void read(I &x) {
    x = 0; I f = 1; char c = gc();
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = gc(); }
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = gc(); }
    x *= f;
}

template<class I>
inline void write(I x) {
    if(x == 0) {putchar('0'); return;}
    I tmp = x > 0 ? x : -x;
    if(x < 0) putchar('-');
    int cnt = 0;
    while(tmp > 0) {
        buf1[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while(cnt > 0) putchar(buf1[--cnt]);
}

#define in(x) read(x)
#define outn(x) write(x), putchar('\n')
#define out(x) write(x), putchar(' ')

} using namespace IO;

/***************快读***************/

#define maxn 1000010

namespace DS{
	template<class T>
	class splay{
		friend
			class INTERFACE;

		private:
			struct Splay_tree{
				int son[2];
				int fa;
				int size;
				int cnt;
				int val;
				int sum;
				int lazy;
			}tree[maxn];

			int tree_cnt,root;

		public:
			void pushup(int ID){
				tree[ID].size=(tree[tree[ID].son[0]].size+tree[tree[ID].son[1]].size+tree[ID].cnt);
				tree[ID].sum=(tree[tree[ID].son[0]].sum+tree[tree[ID].son[1]].sum+tree[ID].val);
			}

			int Son(int ID){
				return tree[tree[ID].fa].son[1]==ID;
			}

			void connect(int x,int y,int k){
				if(x!=0){tree[x].son[k]=y;}
				tree[y].fa=x;
			}

			void rotate(int ID){
				int fa(tree[ID].fa),gra_fa(tree[fa].fa);
				int ty_son(Son(ID)),ty_fa(Son(fa));
				connect(fa,tree[ID].son[ty_son^1],ty_son);
				connect(ID,fa,ty_son^1);
				connect(gra_fa,ID,ty_fa);
				pushup(fa);
				pushup(ID);
				return;
			}

			int NewNode(int val){
				tree[++tree_cnt]=(Splay_tree){{0,0},0,1,1,val,val,0};
				return tree_cnt;
			}

			void Splay(int ID,int goal=0){
				for(int index;(index=tree[ID].fa)!=goal;rotate(ID)){
					if(tree[index].fa!=goal){
						if(Son(index)==Son(ID)){
							rotate(index);
						} else{rotate(ID);}
					}
				}
				if(goal==0){root=ID;}
				return;
			}

			void insert(int val){
				if(!root){root=NewNode(val);return;}
				int index=root;
				while(tree[index].val!=val&&tree[index].son[tree[index].val<val]){index=tree[index].son[tree[index].val<val];}
				if(tree[index].val==val){++tree[index].cnt;Splay(index);return;}
				connect(index,NewNode(val),tree[index].val<val);
				Splay(tree[index].son[tree[index].val<val]);
				return;
			}

			void pushdown(int ID){
				if(tree[ID].lazy){
					tree[tree[ID].son[0]].lazy+=tree[ID].lazy;
					tree[tree[ID].son[1]].lazy+=tree[ID].lazy;
					tree[tree[ID].son[0]].val+=tree[ID].lazy;
					tree[tree[ID].son[1]].val+=tree[ID].lazy;
					tree[tree[ID].son[0]].sum+=tree[tree[ID].son[0]].size*tree[ID].lazy;
					tree[tree[ID].son[1]].sum+=tree[tree[ID].son[1]].size*tree[ID].lazy;
					tree[ID].lazy=0;
				}
			}

			int get_num(int ID){
				int index=root;
				while(19260817){
					pushdown(index);
					if(tree[tree[index].son[0]].size>=ID){
						index=tree[index].son[0];
					} else if(tree[tree[index].son[0]].size+tree[index].cnt<ID){
						ID-=tree[tree[index].son[0]].size+tree[index].cnt;
						index=tree[index].son[1];
					} else{break;}
				}
				return index;
			}

			void add(int l,int r,int val){
				l=get_num(l);
				r=get_num(r+2);
				Splay(l,0);
				Splay(r,l);
				tree[tree[tree[root].son[1]].son[0]].lazy+=val;
				tree[tree[tree[root].son[1]].son[0]].val+=val;
				tree[tree[tree[root].son[1]].son[0]].sum+=tree[tree[tree[root].son[1]].son[0]].size*val;
				pushup(tree[root].son[1]);
				pushup(root);
			}

			int query(int l,int r){
				l=get_num(l);
				r=get_num(r+2);
				Splay(l,0);
				Splay(r,l);
				return tree[tree[tree[root].son[1]].son[0]].sum;
			}
	};

	class INTERFACE{}FC;
}using namespace DS;

int n,m;
int opt,l,r,val;

int a[maxn];

::splay<int> sp;

int main(){
	read(n),read(m);
	sp.insert(0);
	for(int i=1;i<=n;i++){read(a[i]);sp.insert(a[i]);}
	sp.insert(0);
	while(m--){
		read(opt),read(l),read(r);
		switch(opt){
			case 1:{
				read(val);
				sp.add(l,r,val);
				break;
			} default:{
				outn(sp.query(l,r));
				break;
			}
		}
	}
	return 0;
}
2021/8/26 21:21
加载中...