线段树经典题目(一定要做完)

最近学习了好久的线段树,对线段树有了初步的基础的认知,为了巩固知识点找几道基础题练练手uploading.4e448015.gif转存失败重新上传取消

1.hdu1166 敌兵布阵

http://acm.hdu.edu.cn/showproblem.php?pid=1166

思路:线段树基础模版题(点修改+区间查询)

#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=50009;
ll a[maxn];
ll sum[maxn*4];
ll Add[maxn*4];
void getup(int x){
	sum[x]=sum[x*2]+sum[x*2+1];
	return ;
}
void btree(int left,int right,int root)//递归建树
{
	if(left==right){
		sum[root]=a[left];
		return ;
	}
	int mid=(left+right)/2;
	btree(left,mid,root*2);
	btree(mid+1,right,root*2+1);
	getup(root);
}
/*void pushdown(int rt,int ln,int rn){//区间修改时的标记,本题未用到
	if(Add[rt]){
		Add[rt*2]+=Add[rt];
		Add[rt*2+1]+=Add[rt];
		sum[rt*2]+=Add[rt]*ln;
		sum[rt*2+1]+=Add[rt]*rn;
		Add[rt]=0;
	}
}*/
ll  myquery(int L,int R,int l,int r,int rt)//区间查询
{

	if(L<=l&&r<=R)
		return sum[rt];
	int mid=(l+r)/2;
	//pushdown(rt,mid-l+1,r-mid);
	ll  ans=0; 
	if(L<=mid) 
	    ans+=myquery(L,R,l,mid,rt*2);
	if(R>mid) 
		ans+=myquery(L,R,mid+1,r,rt*2+1);
	return ans;
}
void addt(int L,int C,int l,int r,int rt)//点修改
{
	if(l==r){
		sum[rt]+=C;
	    return;
	}
	int mid=(l+r)>>1;
	if(L<=mid)
		addt(L,C,l,mid,rt*2);
	else
		addt(L,C,mid+1,r,rt*2+1);
	getup(rt);
}
int main()
{
	
	int T;
	scanf("%d\n",&T);
	for(int kk=1;kk<=T;kk++)
	{
		int N;
		scanf("%d\n",&N);
		for(int i=1;i<=N;i++)
			scanf("%d",&a[i]);	
		btree(1,N,1);
		char opt[5];
		int num1,num2;
		printf("Case %d:\n",kk);
		while(scanf("%s",opt)&&opt[0]!='E'){
			scanf("%d %d",&num1,&num2);
			if(opt[0]=='Q')
				printf("%lld\n",myquery(num1,num2,1,N,1));
			else if(opt[0]=='A')
				addt(num1,num2,1,N,1);
			else if(opt[0]=='S')
			    addt(num1,-1*num2,1,N,1);
		}
	}
	return 0;
}

  

 

2.I Hate It

http://acm.hdu.edu.cn/showproblem.php?pid=1754

思路:线段树+点修改+区间查询

如果用递归写,MLT,改非递归,AC

ac代码

 

非递归线段树

 

#include
#include
using namespace std;
typedef long long ll;
const ll maxn=200005;
ll Max[maxn*4];
ll a[maxn];
ll N,m,n;
void btree(int x)
{
    N=1;
    while(N0;i--)
    {
        Max[i]=max(Max[i*2],Max[i*2+1]);
    }
}
ll  query(int l,int r)
{
    ll ans=0;
    for(int s=N+l-1,t=N+r+1;s^t^1;s/=2,t/=2)
    {
        if(~s&1) ans=max(ans,Max[s^1]);
        if(t&1)  ans=max(ans,Max[t^1]);
    }
    return ans;
}
void update(int L,int C)
{
    Max[N+L]=C;
    for(int i=(N+L)>>1;i;i>>=1)
    {
        Max[i]=max(Max[i<<1],Max[i<<1|1]);
    }      
}
int main()
{
    while(scanf("%lld %lld",&n,&m)!=EOF){
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
            getchar();
        btree(n);
        char op[2];
        ll num1,num2;
        for(int kk=0;kk

 

待续~~~~~~~

 

 

 

你可能感兴趣的:(数据结构学习与练习)