线段树备份

root 站长 2024-08-18 11:03:56 10
#include<bits/stdc++.h>

using namespace std;

int n,m;
int a[400010];
int sum[400010];
int s[4000010];
int maxsum;
int Pow;
int ans1,ans2;

void Build(int id,int l,int r)
{
	if(l == r)
	{
		maxsum = max(maxsum,id);
		sum[id] = 1;
		s[id] = 1;
		return;
	}
	int mid = l + r >> 1;
	Build(id * 2,l,mid);
	Build(id * 2 + 1,mid + 1,r);
	sum[id] = sum[id * 2] + sum[id * 2 + 1];
	s[id] = s[id * 2] + s[id * 2 + 1];
	maxsum = max(maxsum,id);
}

void unplant(int id,int l,int r,int x,int y)//砍树 
{
	if(l < x && r < x || l > y && r > y)
	{
		return;
	}
	if(l == r)
	{
		if(s[id] == 2)
		{
			ans2 ++;
		}
		sum[id] = 0;
		s[id] = 0; 
		return;
	}
	int mid = l + r >> 1;
	unplant(id * 2,l,mid,x,y);
	unplant(id * 2 + 1,mid + 1,r,x,y);
	sum[id] = sum[id * 2] + sum[id * 2 + 1];
}

void plant(int id,int l,int r,int x,int y)
{
	if(l < x && r < x || l > y && r > y)
	{
		return;
	}
	if(l == r)
	{
		if(sum[id] == 0) s[id] = 2,ans1 ++;
		sum[id] = 1;
		return;
	}
	int mid = l + r >> 1;
	plant(id * 2,l,mid,x,y);
	plant(id * 2 + 1,mid + 1,r,x,y);
	sum[id] = sum[id * 2] + sum[id * 2 + 1];
}

int main()
{
	scanf("%d%d",&n,&m);
	Build(1,1,n);
	for(int i = 1;i <= m;i ++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		if(x == 0)
		{
			unplant(1,1,n,y,z);
		}
		else
		{
			plant(1,1,n,y,z);
		}
	}
	printf("%d\n%d",ans1 - ans2,ans2);
	return 0;
}
{{ vote && vote.total.up }}

共 1 条回复

root 站长
#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int n, m;
int a[4*N], sum[4*N], maxv[4*N], minv[4*N];

void build(int id, int l, int r)
{
	if (l == r)
	{
		sum[id] = a[l];
		maxv[id] = a[l];
		minv[id] = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(id * 2, l, mid);
	build(id * 2 + 1, mid + 1, r);
	sum[id] = sum[2*id] + sum[2*id+1];
	maxv[id] = max(maxv[2*id], maxv[2*id+1]);
	minv[id] = min(minv[2*id], minv[2*id+1]);
}

int query_min(int id, int l, int r, int x, int y)
{
	if (x <= l && r <= y)
	{
		return minv[id];
	}
	int mid = l + r >> 1;
	int ans = INF;
	if (x <= mid) ans = min(ans, query_min(id *2, l, mid, x, y));
	if (y > mid) ans = min(ans, query_min(id*2+1, mid+1, r, x, y));
	return ans;
}

void update_point(int id, int l, int r, int x, int y)
{
	if (l == r)
	{
		minv[id] = maxv[id] = sum[id] = y;
		return;
	}
	int mid = l + r >> 1;
	if (x <= mid) update_point(id*2, l, mid, x, y);
	else update_point(id*2+1, mid+1, r, x, y);
	sum[id] = sum[2*id] + sum[2*id+1];
	maxv[id] = max(maxv[2*id], maxv[2*id+1]);
	minv[id] = min(minv[2*id], minv[2*id+1]);
}
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
	build(1, 1, n);
	while (m -- )
	{
		int op, x, y;
		scanf("%d%d%d", &op, &x, &y);
		if (op == 1) printf("%d ", query_min(1, 1, n, x, y));
		else update_point(1, 1, n, x, y);
	}
	return 0;	
}