zoukankan      html  css  js  c++  java
  • 线段树专题之单点更新(最基础的线段树,只更新叶子节点,然后把信息更新)

    HDU1166(区间求和)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define lson l,m,rt<<1              //定义左儿子
    #define rson m+1,r,rt<<1|1          //定义右儿子
    using namespace std;
    const int maxn=50001;
    int sum[maxn<<2];
    void pushUP(int rt)                 //更新到父结点
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void build(int l,int r,int rt)      //建立树
    {
        if(l==r)
        {
            scanf("%d",&sum[rt]);
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        pushUP(rt);
    }
    void update(int p,int add,int l,int r,int rt)  //单点增减
    {
        if(l==r)
        {
            sum[rt]+=add;
            return;
        }
        int m=(l+r)>>1;
        if(p<=m)  update(p,add,lson);
        else    update(p,add,rson);
        pushUP(rt);
    }
    int query(int L,int R,int l,int r,int rt)    //区间求和
    {
        if(L<=l&&r<=R)
            return sum[rt];
        int m=(l+r)>>1;
        int ret=0;
        if(L<=m)   ret+=query(L,R,lson);
        if(R>m)   ret+=query(L,R,rson);
        return ret;
    }
    int main()
    {
        int T,n;
        scanf("%d",&T);
        for(int cas=1;cas<=T;cas++)
        {
            printf("Case %d:
    ",cas);
            scanf("%d",&n);
            build(1,n,1);
            char op[10];
            while(scanf("%s",op))
            {
                if(op[0]=='E') break;
                int a,b;
                scanf("%d%d",&a,&b);
                if(op[0]=='Q')
                    printf("%d
    ",query(a,b,1,n,1));
                else if(op[0]=='S')
                    update(a,-b,1,n,1);
                else
                    update(a,b,1,n,1);
            }
        }
        return 0;
    }

    HDU  1754(区间最大值)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754

    本人AC的第一道线段树,纪念一下,下面贴解题代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int maxn=200001;
    int sum[maxn<<2];
    void pushUP(int rt)
    {
    	sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
    }
    void build(int l,int r,int rt)
    {
    	if(l==r)
    	{
    		scanf("%d",&sum[rt]);
    		return;
    	}
    	int m=(l+r)/2;
    	build(lson);
    	build(rson);
    	pushUP(rt);
    }
    void update(int p,int s,int l,int r,int rt)
    {
    	if(l==r)
    	{
    		sum[rt]=s;
    		return;
    	}
    	int m=(l+r)/2;
    	if(p<=m)  update(p,s,lson);
    	else update(p,s,rson);
    	pushUP(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
    	if(L<=l&&r<=R)
    	return sum[rt];
    	int m=(l+r)/2;
    	int ret=0;
    	if(L<=m) 
    	ret=max(ret,query(L,R,lson));
    	if(R>m) 
    	ret=max(ret,query(L,R,rson));
    	return ret;
    }
    int main()
    {
    	int n,m;
    	while(cin>>n>>m)
    	{
    		build(1,n,1);
    		while(m--)
    		{
    			char op[2];
    			int a,b;
    			scanf("%s%d%d",op,&a,&b);
    			if(op[0]=='Q')
    			printf("%d
    ",query(a,b,1,n,1));
    			else
    			update(a,b,1,n,1);
    		}
    	}
    	return 0;
    }


    HDU1394(求最小逆序数)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394

    思路:对于一个数x[i],将其移至最后其逆序数的数量相当于减去比x[i]小的数再加上比x[i]大的数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    const int maxn=5001;
    int sum[maxn<<2];       
    void pushUP(int rt)                     //更新父节点 
    {
    	sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void build(int l,int r,int rt)        //建树 
    {
    	sum[rt]=0;
    	if(l==r)
    	return;
    	int m=(l+r)/2;
    	build(lson);
    	build(rson);
    }
    void update(int p,int l,int r,int rt)    //单点增减 
    {
    	if(l==r)
    	{
    		sum[rt]++;
    		return;
    	}
    	int m=(l+r)/2;
    	if(p<=m)   update(p,lson);
    	else  update(p,rson);
    	pushUP(rt);
    }
    int query(int L,int R,int l,int r,int rt)   //区间求和 
    {
    	if(L<=l&&r<=R)
    	return sum[rt];
    	int m=(l+r)/2;
    	int ret=0;
    	if(L<=m)    ret+=query(L,R,lson);
    	if(R>m)   ret+=query(L,R,rson);
    	return ret;
    }
    int x[maxn];
    int main()
    {
    	int n;
    	while(cin>>n)
    	{
    		build(0,n-1,1);
    		int sum=0;
    		for(int i=0;i<n;i++)
    		{
    			scanf("%d",&x[i]);
    			sum+=query(x[i],n-1,0,n-1,1);
    			update(x[i],0,n-1,1);
    		}
    		int ret=sum;
    		for(int i=0;i<n;i++)          //将x[i]移至尾部的其值为减去比x[i]小的,加上比x[i]大的 
    		{
    			sum+=n-1-x[i]-x[i];
    			ret=min(ret,sum);
    		}
    		cout<<ret<<endl;
    	}
    	return 0;
    }


    HDU2795

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795

    题解:每次找到最大值的位子,然后减去L
    线段树功能:query:区间求最大值的位子(直接把update的操作在query里做了)


    #include <cstdio>
    #include <algorithm>
    using namespace std;
     
    #define lson l , m , rt << 1
    #define rson m + 1 , r , rt << 1 | 1
    const int maxn = 222222;
    int h , w , n;
    int MAX[maxn<<2];
    void PushUP(int rt) {
    	MAX[rt] = max(MAX[rt<<1] , MAX[rt<<1|1]);
    }
    void build(int l,int r,int rt) {
    	MAX[rt] = w;
    	if (l == r) return ;
    	int m = (l + r) >> 1;
    	build(lson);
    	build(rson);
    }
    int query(int x,int l,int r,int rt) {
    	if (l == r) {
    		MAX[rt] -= x;
    		return l;
    	}
    	int m = (l + r) >> 1;
    	int ret = (MAX[rt<<1] >= x) ? query(x , lson) : query(x , rson);
    	PushUP(rt);
    	return ret;
    }
    int main() {
    	while (~scanf("%d%d%d",&h,&w,&n)) {
    		if (h > n) h = n;
    		build(1 , h , 1);
    		while (n --) {
    			int x;
    			scanf("%d",&x);
    			if (MAX[1] < x) puts("-1");
    			else printf("%d
    ",query(x , 1 , h , 1));
    		}
    	}
    	return 0;
    }

  • 相关阅读:
    ubuntu14.04 Cannot find OpenSSL's <evp.h>
    git 常用命令
    Python3常用模块的安装
    Centos7 安装配置优化mysql(mariadb分支)
    Centos7 编译安装python3
    Centos6.5搭建git远程仓库
    年轻
    springboot 报错Field XXX required a bean of type XXX that could not be found.
    springboot 启动报错[classpath:/application.yml] but snakeyaml was not found on the classpath
    idea 使用点击maven clean/install或maven其他命令失败,显示:乱码+archetypeCatalog=internal
  • 原文地址:https://www.cnblogs.com/wolf940509/p/6617130.html
Copyright © 2011-2022 走看看