Splay 20pts求调
查看原帖
Splay 20pts求调
716260
SegmentTree_楼主2024/6/28 00:20
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lid (id << 1)
#define rid (id << 1 | 1)
#define int long long
const int N = 1e5+5;
struct node{
	int son[2];
	int val;
	int cnt;
	int siz;
	int fa;
	int val1;
	int sum;
	int lazy;
}tr[2000005];
int root, tot;
int n, m;
int a[N];
bool Dir(int x){
	return tr[tr[x].fa].son[1] == x;
}
void pushup(int x){
	tr[x].siz = tr[tr[x].son[0]].siz + tr[tr[x].son[1]].siz + tr[x].cnt;
	tr[x].sum = tr[x].val1 * tr[x].cnt + tr[tr[x].son[0]].sum + tr[tr[x].son[1]].sum;
}
void pushdown(int x){
	if (x && tr[x].lazy){
		tr[tr[x].son[0]].lazy += tr[x].lazy;
		tr[tr[x].son[1]].lazy += tr[x].lazy;
		tr[tr[x].son[0]].val1 += tr[x].lazy;
		tr[tr[x].son[1]].val1 += tr[x].lazy;
		tr[tr[x].son[0]].sum += tr[x].lazy * tr[tr[x].son[0]].siz;
		tr[tr[x].son[1]].sum += tr[x].lazy * tr[tr[x].son[1]].siz;
		tr[x].lazy = 0;
	}
}
void rorate(int x){
	int y = tr[x].fa, z = tr[y].fa, k = Dir(x), w = tr[x].son[k ^ 1];
	pushdown(x), pushdown(y);
	tr[z].son[Dir(y)] = x;tr[x].fa = z;
	tr[x].son[k ^ 1] = y;tr[y].fa = x;
	tr[y].son[k] = w;tr[w].fa = y;
	pushup(x);pushup(y);
}
void splay(int x, int goal = 0){
	while (tr[x].fa != goal){
		int y = tr[x].fa, z = tr[y].fa;
		if (z != goal){
			if (Dir(x) == Dir(y)) rorate(y);
			else rorate(x);
		}
		rorate(x);
	}
	if (!goal) root = x;
}
int find(int k){ 
	int cur = root;
	while (1){
		pushdown(cur);
		if (tr[cur].son[0] && k <= tr[tr[cur].son[0]].siz){
			cur = tr[cur].son[0];
		}
		else{
			int tmp = (tr[cur].son[0] ? tr[tr[cur].son[0]].siz : 0) + tr[cur].cnt;
			if (k <= tmp){
				return cur;
			}
			k -= tmp;
			cur = tr[cur].son[1];
		}
	}
}
void print(int x){
	pushdown(x);
	if (tr[x].son[0])print(tr[x].son[0]);
	int tmp = tr[x].val, tmp1 = tr[x].sum;
	if (tmp >= 1 && tmp <= n) cout << tmp << ' ' << tmp1 << '\n';
	if (tr[x].son[1]) print(tr[x].son[1]); 
}
void insert(int x, int v){
	int cur = root, p = 0;
	while (cur && tr[cur].val != x){
		p = cur;
		cur = tr[cur].son[x > tr[cur].val];
	}
	if (cur) ++tr[cur].cnt;
	else{
		cur = ++tot;
		if (p) tr[p].son[x > tr[p].val] = cur;
		tr[cur].son[0] = tr[cur].son[1] = tr[cur].sum = 0;
		tr[cur].val = x;
		tr[cur].fa = p;
		tr[cur].val1 = v;
		tr[cur].siz = tr[cur].cnt = 1;
	}
	splay(cur);
}
int query(int l, int r){
	int a = l - 1, b = r + 1;
	a = find(a);
	b = find(b);
	splay(a), splay(b, a);
	int cur = tr[root].son[1];
	cur = tr[cur].son[0];
	//print(cur);
	return tr[cur].sum;
}
void add(int l, int r, int k){
	int a = l - 1, b = r + 1;
	a = find(a);
	b = find(b);
	splay(a), splay(b, a);
	int cur = tr[root].son[1];
	cur = tr[cur].son[0];
	tr[cur].lazy += k;
	tr[cur].val1 += k;
	tr[cur].sum += k * tr[cur].siz;
	pushup(tr[cur].son[1]);
	pushup(cur);
}
signed main(){
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	insert(-INT_MAX, 0);
	for (int i = 1;i<= n;i++){
		int v;
		cin >> v;
		insert(i, v);
	}
	insert(INT_MAX, 0);
	//print(root);
	//cout << '\n';
	while (m--){
		int op, l, r;
		cin >> op >> l >> r;
		if (op == 1){
			int k;
			cin >> k;
			add(l + 1, r + 1, k);
		}
		else{
			cout << query(l + 1, r + 1) << '\n';
		}
	}
	return 0;
}
2024/6/28 00:20
加载中...