区间信息的维护与查询

连续查询问题

文章共3部分:

1.二叉索引树(树状数组)

2.RMQ问题

3.线段树:点修改

1.二叉索引树(树状数组)

#include<iostream>
using namespace std;
int A[10020]={},C[10020]={};
int n,m;
inline int lowbit(int x){return x&(-x);}
int sum(int x)
{
	int ret=0;
	while(x)
	{
		ret+=C[x];
		x-=lowbit(x);
	}
	return ret;
}
void add(int x,int d)
{
	while(x<=n)
	{
		C[x]+=d;
		x+=lowbit(x);
	}
}
int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)cin>>A[i];
	for(int i=0;i<n;i++)
	{
		for(int j=1;j<=lowbit(i);j++)
		C[i]+=A[i-lowbit(i)+j];
	}
	for(int i=0;i<m;i++)
	{
		char ch;
		cin>>ch;
		if(ch=='S')
		{
			int x;
			cin>>x;
			cout<<sum(x)<<endl;
		}
		if(ch=='A')
		{
			int x,d;
			cin>>x>>d;
			add(x,d);
		}
	}
	return 0;
}
2.RMQ问题

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int d[502][502]={};
void RMQ_init(const vector<int>& A)
{
	int n=A.size();
	for(int i=0;i<n;i++)d[i][0]=A[i];
	for(int j=1;(1<<j)<=n;j++)
	for(int i=0;i+(1<<j)-1<n;i++)
	d[i][j]=min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
int RMQ(int L,int R)
{
	int k=0;
	while((1<<(k+1))<=R-L+1)k++;
	return min(d[L][k],d[R-(1<<k)+1][k]);
}
int main()
{
	vector<int> a;
	int n,q,aa;
	cin>>n>>q;
	for(int i=0;i<n;i++)
	{
		cin>>aa;
		a.push_back(aa); 
	}
	RMQ_init(a);
	while(q--)
	{
		int l,r;
		cin>>l>>r;
		cout<<RMQ(l,r)<<endl;
	}
	return 0;
}
3.线段树:点修改

#include<iostream>
#include<algorithm>
using namespace std;
#define INF 1<<28
int minv[10020]={};
int ql,qr;
int Query(int o,int L,int R)
{
	int M=L+(R-L)/2,ans=INF;
	if(ql<=L&&R<=qr)return minv[o];
	if(ql<=M)ans=min(ans,Query(o*2,L,M));
	if(qr>M)ans=min(ans,Query(o*2+1,M+1,R));
	return ans;
}
int p,v;
void Update(int o,int L,int R)
{
	int M=L+(L+R)/2;
	if(L==R)minv[o]=v;
	else
	{
		if(p<=M)Update(o*2,L,M);
		else Update(o*2+1,M+1,R);
		minv[o]=min(minv[o*2],minv[o*2+1]);
	}
}
int main()
{
	int n,m;char ch;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		cin>>v;
		minv[i]=v;
	}
	for(int i=0;i<m;i++)
	{
		cin>>ch;
		if(ch=='Q')
		{
			cout<<Query(0,0,n)<<endl;
		}
		if(ch=='U')
		{
			cin>>p>>v;
			Update(0,0,n);
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值