zoukankan      html  css  js  c++  java
  • poj3468线段树_区间数字统计

       自从上次偶尔用了一次线段树后就很喜欢这东西,做各种区间统计挺有用的。抽空又玩了下3468。也是一道很常见的数段树应用,统计区间的和,有时候又要更新区间的值。

    #include<iostream>

    using namespace std;

    class TreeNode
    {
    public:
    int lIndex,rIndex;
    TreeNode *lNode;
    TreeNode *rNode;
    __int64 inc;
    __int64 sum;
    };

    //根据给定的数组建树
    void BuildTree(TreeNode *tNode,int lIndex,int rIndex)
    {
    tNode->lIndex=lIndex;
    tNode->rIndex=rIndex;
    tNode->inc=0;

    int midIndex=(lIndex+rIndex)/2;

    if(midIndex<rIndex)
    {
    tNode->lNode=new TreeNode();
    BuildTree(tNode->lNode,lIndex,midIndex);
    }
    if(midIndex+1>lIndex && midIndex+1<=rIndex)
    {
    tNode->rNode=new TreeNode();
    BuildTree(tNode->rNode,midIndex+1,rIndex);
    }
    return ;
    }

    //初始化区间的和
    __int64 InitTreeNodeSum(TreeNode *tnode,int arr[])
    {
    if(tnode==NULL)return 0;
    if(tnode->lIndex==tnode->rIndex)
    {
    tnode->sum=arr[tnode->lIndex];

    }

    else
    {
    __int64 leftSum=InitTreeNodeSum(tnode->lNode,arr);
    __int64 rightSum=InitTreeNodeSum(tnode->rNode,arr);
    tnode->sum=leftSum+rightSum;
    }
    return tnode->sum;
    }

    //增加操作
    void AddSubSequence(TreeNode *tNode,int lIndex,int rIndex,int tInc)
    {
    if(lIndex==tNode->lIndex && rIndex==tNode->rIndex)
    {
    tNode->inc+=tInc;
    return;
    }

    else
    {
    tNode->sum += (rIndex-lIndex+1)*tInc;

    if(rIndex <= tNode->lNode->rIndex)//totally in the left child
    {
    AddSubSequence(tNode->lNode,lIndex,rIndex,tInc);
    }

    else if(lIndex >= tNode->rNode->lIndex)//totally in the right child
    {
    AddSubSequence(tNode->rNode,lIndex,rIndex,tInc);
    }

    else
    {
    AddSubSequence(tNode->lNode,lIndex,tNode->lNode->rIndex,tInc);
    AddSubSequence(tNode->rNode,tNode->rNode->lIndex,rIndex,tInc);
    }
    }
    }

    //询问操作
    __int64 QuerySequence(TreeNode *tNode,int lIndex,int rIndex,int parentInc)
    {
    if(tNode->lIndex==lIndex && tNode->rIndex==rIndex)
    {
    __int64 sum = tNode->sum+(tNode->rIndex-tNode->lIndex+1)*(tNode->inc+parentInc);
    return sum;
    }
    else
    {
    if(rIndex <= tNode->lNode->rIndex)//totally in the left child
    {
    return QuerySequence(tNode->lNode,lIndex,rIndex,tNode->inc+parentInc);
    }

    else if(lIndex >= tNode->rNode->lIndex)//totally in the right child
    {
    return QuerySequence(tNode->rNode,lIndex,rIndex,tNode->inc+parentInc);
    }

    else
    {
    return QuerySequence(tNode->lNode,lIndex,tNode->lNode->rIndex,tNode->inc+parentInc) + 
    QuerySequence(tNode->rNode,tNode->rNode->lIndex,rIndex,tNode->inc+parentInc);
    }
    }
    }

    int main()
    {
    int N,Q;
    int inArray[100001];
    scanf("%d%d",&N,&Q);
    for(int i=1;i<=N;i++)
    {
    scanf("%d",&inArray[i]);
    }

    TreeNode treeRoot;
    BuildTree(&treeRoot,1,N);

    InitTreeNodeSum(&treeRoot,inArray);

    for (int i=0;i<Q;i++)
    {
    char ch=' ';
    int a,b,c;
            while(!(ch == 'Q' || ch=='C'))
    scanf("%c",&ch);
    if(ch=='Q')
    {
    scanf("%d%d",&a,&b);
    __int64 sum=QuerySequence(&treeRoot,a,b,0);
    printf("%lld\n",sum);
    }
    else
    {
    scanf("%d%d%d",&a,&b,&c);
    AddSubSequence(&treeRoot,a,b,c);
    }
    }
    return 0;
    }
  • 相关阅读:
    List 与 Array 的相互转化及 List、Array、Set转为 String
    Java 序列化介绍及 Redis 序列化方式
    SpringBoot 整合 redis 实现 token 验证
    SpringBoot 整合 Redis 使用
    Map 某 value 为 对象数组,转为 ArrayList 对象集合
    JWT 基本使用
    Spring session + redis 实现 session共享入门
    HttpServletRequest + Filter 添加 header
    Git ahead(超前) 又behind(落后)
    web应用中路径跳转问题-相对路径、绝对路径
  • 原文地址:https://www.cnblogs.com/bester/p/3255770.html
Copyright © 2011-2022 走看看