这道题 #6 就真的针对动态开点权值线段树是吧
  • 板块学术版
  • 楼主wangyibo201026
  • 当前回复7
  • 已保存回复7
  • 发布时间2023/3/8 11:29
  • 上次更新2023/10/23 22:43:14
查看原帖
这道题 #6 就真的针对动态开点权值线段树是吧
363006
wangyibo201026楼主2023/3/8 11:29

RT。值域少一点会 WA,多一点会 RE,把数组开大一点又会 MLE,真的服了。

代码:

#include<bits/stdc++.h>
#define int long long

using namespace std;

const int N = 4e5 * 34 + 5;
const int M = 1e5 + 5;

int n, m, cnt, rt, L, R, ans;
int sum[N], a[N];

struct Node{
	int tag, val;
	int ls, rs;
}tree[N];

void pushup(int node){
	tree[node].val = tree[tree[node].ls].val + tree[tree[node].rs].val;
}

void addtag(int &node, int lt, int rt, int val){
	if(!node){
		node = ++cnt;
	}
	tree[node].val += (rt - lt + 1) * val;
	tree[node].tag += val;
}

void pushdown(int node, int lt, int rt){
	if(lt >= rt){
		return ;
	}
	int mid = lt + rt - 1 >> 1;
	addtag(tree[node].ls, lt, mid, tree[node].tag);
	addtag(tree[node].rs, mid + 1, rt, tree[node].tag);
	tree[node].tag = 0;
}

void update(int node, int lt, int rt, int x, int y, int val){
	if(y < lt || x > rt){
		return ;
	}
	if(x <= lt && rt <= y){
		addtag(node, lt, rt, val);
		return ;
	}
	pushdown(node, lt, rt);
	int mid = lt + rt - 1 >> 1;
	update(tree[node].ls, lt, mid, x, y, val);
	update(tree[node].rs, mid + 1, rt, x, y, val);
	pushup(node);
}

int query(int node, int lt, int rt, int x, int y){
	if(y < lt || x > rt){
		return 0;
	}
	if(x <= lt && rt <= y){
		return tree[node].val;
	}
	pushdown(node, lt, rt);
	int mid = lt + rt - 1 >> 1;
	return query(tree[node].ls, lt, mid, x, y) + query(tree[node].rs, mid + 1, rt, x, y);
}

signed main(){
	cin >> n >> L >> R;
	rt = cnt = 1;
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		sum[i] = sum[i - 1] + a[i];
	}
	update(rt, -8000000000, 8000000000, sum[0], sum[0], 1);
	for(int i = 1; i <= n; i++){
		ans += query(rt, -8000000000, 8000000000, min(sum[i] - R, sum[i] - L), max(sum[i] - R, sum[i] - L));
		update(rt, -8000000000, 8000000000, sum[i], sum[i], 1); 
	}
	cout << ans;
	return 0;
}
2023/3/8 11:29
加载中...