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

52 篇文章 0 订阅
10 篇文章 0 订阅

第一次写线段树题,写的是静态的飘过~~~

线段树:它主要用于处理一段连续区间的插入,查找,统计,查询等操作。
复杂度: 设区间长度是n,所有操作的复杂度是logn级别。

一线段树的建图有两种。

1、最后一层建成线段,就是所有区间都是开区间,最后一层是[1,2]  [2,3] [3,4]。。。。。。

2、最后一层建成点,类似[1,1]  [2,2]..

二、更新

1、注意更新父节点对子节点的影响。

2、注意更新子节点对父节点的影响。

AC代码:

#include<iostream>
#include<string.h>
#include<algorithm>
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y)((x+y)>>1)
using namespace std;
typedef struct str
{
	int l;
	int r;
	int key;
}Node;
Node node[100001*4];
void build(int t,int l,int r)//建树
{
	node[t].l=l;node[t].r=r;
	node[t].key=1;
	if(l==r-1) return;
	int mid=MID(l,r);
	build(L(t),l,mid);
	build(R(t),mid,r);
}
void update(int t,int l,int r,int sum)//更新
{
	if(l==node[t].l&&r==node[t].r)
	{
		node[t].key=sum;
		return;
	}
	if(node[t].key>0)
	{
		node[L(t)].key=node[t].key;
		node[R(t)].key=node[t].key;
		node[t].key=-1;
	}
	int mid=MID(node[t].l,node[t].r);
	if(l>=mid) update(R(t),l,r,sum);
	else{
		if(r<=mid) update(L(t),l,r,sum);
		else
		{
			update(R(t),mid,r,sum);
			update(L(t),l,mid,sum);
		}
	}
}
int Quary(int t,int l,int r)//查找
{
	if(node[t].key>0)
		return node[t].key*(r-l);
	int mid=MID(node[t].l,node[t].r);
	 return Quary(R(t),mid,r)+Quary(L(t),l,mid);
	/*if(l>=mid) return Quary(R(t),l,r);
	else
	{
		if(r<=mid) return Quary(L(t),l,r);
		else
		{
			return Quary(R(t),mid,r)+Quary(L(t),l,mid);
		}
	}*/
	
}
int main()
{
	int T;
	cin>>T;
	int tot=0;
	while(T--)
	{
		int n;
		cin>>n;
		build(1,0,n);
		int m;
		cin>>m;
		while(m--)
		{
			int x,y,z;
			cin>>x>>y>>z;
			update(1,x-1,y,z);
		 }
		printf("Case %d: The total value of the hook is %d.\n",++tot,Quary(1,0,n));
    }return 0;

}

动态:

#include<iostream>
#include<string.h>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef struct NODE
{
    struct NODE *lc,*rc;
    int ld,rd;
    int key;
    NODE()
    {
        key=1;
    }
}*Node,T;
class rmq{ 
public:
    Node root;
     rmq()
     {
         root=new T;
     }
     ~rmq()
     {
         delete root;
     }
         Node build(int a,int b);
         void update(Node root ,int l,int r,int sum);
         int Quary(Node root,int l,int r);
};
Node rmq::build(int a,int b)
{   
    Node root=new T;
    root->ld=a;
    root->rd=b;
    if(a==b-1) return root;
    int mid=(a+b)>>1;
    root->lc=build(a,mid);
    root->rc=build(mid,b);
    return root;
}
void rmq::update(Node root,int l,int r,int sum)
{
    if(root->ld==l&&root->rd==r)
    {  root->key=sum;
       return;
    }
	if(root->key==sum) return;
    if(root->key>0)
    {
        root->lc->key=root->key;
        root->rc->key=root->key;
        root->key=-1;
    }
    int mid=(root->ld+root->rd)>>1;
    if(l>=mid) update(root->rc,l,r,sum);
     else
    {
        if(r<=mid) update(root->lc,l,r,sum);
                   
        else
        {
            update(root->lc,l,mid,sum);
            update(root->rc,mid,r,sum);
        }
    }
}
int rmq::Quary(Node root,int l,int r)
{
    if(root->key>0)
        return root->key*(root->rd-root->ld);
    int mid=(root->ld+root->rd)>>1;
     return Quary(root->lc,l,mid)+Quary(root->rc,mid,r);
}
int main()
{
    int T;
    cin>>T;
    int tot=0;
    while(T--)
    {
        int n;
        cin>>n;
        rmq s;
        s.root=s.build(0,n);
        int m;
        cin>>m;
        while(m--)
        {
            int x,y,z;
            cin>>x>>y>>z;
            s.update(s.root,x-1,y,z);
        }
        printf("Case %d: The total value of the hook is %d.\n",++tot,s.Quary(s.root,0,n));
    }return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值