zoukankan      html  css  js  c++  java
  • 线段树 POJ 3468

      这周学习了一下线段树,偶遇POJ 3468,这道题是线段树区间更新,题意大概是有一段的长为n的数组,经过若干次对其中某一段的数进行加减,询问某一段的和。这题还是比较明显的线段树,如果细分到对每一个节点进行操作的话,复杂度为O(m^logn),容易超时,所以采取延迟标记的做法,直接对某一段进行操作,而暂不对其子树进行操作,话不多说,直接上代码吧

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include <iostream>  
    #include<algorithm>
    #include<cmath>
    using  namespace  std; 
    
    struct node 
    {
        int x,y,sign;
        long long sum,ad; 
    } ;
    
    node tree[400010];
    long long v[100010];
    
    long long maketree(int x,int y,int z)
    {
        tree[z].x=x;
        tree[z].y=y;
        if(x>=y) return tree[z].sum=v[x];
        else return tree[z].sum=maketree(x,(x+y)/2,2*z)+maketree((x+y)/2+1,y,2*z+1);
    }
    
    void down(int q)
    {
        tree[q].sign=0;
        tree[2*q].sign=tree[2*q+1].sign=1;
        tree[2*q].ad+=tree[q].ad;
        tree[2*q+1].ad+=tree[q].ad;
        tree[2*q].sum+=tree[q].ad*(tree[2*q].y-tree[2*q].x+1);
        tree[2*q+1].sum+=tree[q].ad*(tree[2*q+1].y-tree[2*q+1].x+1);
        tree[q].ad=0;
    }
    
    void add(int x,int y,int z,int q)
    {
        if(x<=tree[q].x&&y>=tree[q].y) 
        {
            tree[q].sign=1;
            tree[q].sum+=z*(tree[q].y-tree[q].x+1);
            tree[q].ad+=z;
            return ;
        }
        if(tree[q].sign==1) down(q);
        if(x<=(tree[q].x+tree[q].y)/2) add(x,y,z,2*q);
        if(y>=(tree[q].x+tree[q].y)/2+1) add(x,y,z,2*q+1);
        tree[q].sum=tree[2*q].sum+tree[2*q+1].sum;
        return; 
    }
    
    long long find(int x,int y,int q)
    {
        if(x>tree[q].y||y<tree[q].x) return 0;
        if(x<=tree[q].x&&y>=tree[q].y) return tree[q].sum;
        if(tree[q].sign==1) down(q);
        return find(x,y,2*q)+find(x,y,2*q+1);
    }
    
    int main()
    {
        int n,q,x,y,z,i,k;
        long long sum;
        char ch;
        scanf("%d%d",&n,&q);
        memset(tree,0,sizeof(tree));
        for(k=1;k<=n;k++)
        {
            scanf("%lld",&v[k]);
        }
        maketree(1,n,1);
        for(i=1;i<=q;i++)
        {
            scanf("%*c%c",&ch);
            if(ch=='C')
            {
                scanf("%d%d%d",&x,&y,&z);
                add(x,y,z,1);
            }
            else if(ch=='Q')
            {
                scanf("%d%d",&x,&y);
                sum=find(x,y,1);
                printf("%lld
    ",sum);
            }
        }
        return 0;
    }
  • 相关阅读:
    将vue文件script代码抽取到单独的js文件
    git pull 提示错误:Your local changes to the following files would be overwritten by merge
    vue和uniapp 配置项目基础路径
    XAMPP Access forbidden! Access to the requested directory is only available from the local network.
    postman与newman集成
    postman生成代码段
    Curl命令
    POST方法的Content-type类型
    Selenium Grid 并行的Web测试
    pytorch转ONNX以及TnesorRT的坑
  • 原文地址:https://www.cnblogs.com/5299bbcl/p/4540886.html
Copyright © 2011-2022 走看看