zoukankan      html  css  js  c++  java
  • 线段树——快速区间查找

        线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。
        使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩。

    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<iomanip>
    #include<string>
    #include<climits>
    #include<cmath>
    #include<time.h>
    #define MAX 120000
    using namespace std;
    int n,m;
    int ans;
    struct Tree
    {
        int l,r;
        int sum,add;
    };
    Tree tree[MAX*3];
    void pushup(int x)
    {
        int tmp=2*x;
        tree[x].sum=tree[tmp].sum+tree[tmp+1].sum;
    }
    void pushdown(int x)
    {
        int tmp=2*x;
        tree[tmp].add+=tree[x].add;
        tree[tmp+1].add+=tree[x].add;
        tree[tmp].sum+=tree[x].add*(tree[tmp].r-tree[tmp].l+1);
        tree[tmp+1].sum+=tree[x].add*(tree[tmp+1].r-tree[tmp+1].l+1);
        tree[x].add=0;
    }
    
    void build(int l,int r,int x)
    {
        tree[x].l=l;
        tree[x].r=r;
        tree[x].add=0;
        if(l==r)
        {
            tree[x].sum=0;
            return ;
        }
        int tmp=x<<1;
        int mid=(l+r)>>1;
        build(l,mid,tmp);
        build(mid+1,r,tmp+1);
        pushup(x);
    }
    
    
    void update(int l,int r,int c,int x)
    {
        if(r<tree[x].l||l>tree[x].r)
            return ;
        if(l<=tree[x].l&&r>=tree[x].r)
        {
            tree[x].add+=c;
            tree[x].sum+=c*(tree[x].r-tree[x].l+1);
            return ;
        }
        if(tree[x].add)
            pushdown(x);
        int tmp=x<<1;
        update(l,r,c,tmp);
        update(l,r,c,tmp+1);
        pushup(x);
    }
    void query(int l,int r,int x)
    {
        if(r<tree[x].l||l>tree[x].r)
            return ;
        if(l<=tree[x].l&&r>=tree[x].r)      
        {
            ans+=tree[x].sum;
            return ;
        }
        if(tree[x].add)
            pushdown(x);
        int tmp=x<<1;
        int mid=(tree[x].l+tree[x].r)>>1;
        if(r<=mid)
            query(l,r,tmp);
        else if(l>mid)
            query(l,r,tmp+1);
        else
        {
            query(l,mid,tmp);
            query(mid+1,r,tmp+1);
        }
    }
    
    
    int main()
    {
        //freopen("input2.txt","r",stdin);
        //freopen("output2.txt","w",stdout);
        scanf("%d %d",&n,&m);    
        build(1,n,1);//建树
        int str0;
        while(m--){
            scanf("%d",&str0);
            if(str0==2){
                int l;
                scanf("%d",&l);
                ans=0;
                query(l,l,1);
                printf("%d
    ",ans);
            }
            else if(str0==1){
                int l,r;
                scanf("%d %d",&l,&r);
                update(l,r,1,1);
            }
        }
        return 0;
    }
    
            
  • 相关阅读:
    1061. 判断题(15)
    1070. 结绳(25)
    1069. 微博转发抽奖(20)
    1068. 万绿丛中一点红(20)
    1067. 试密码(20)
    DB2sql关键字——ALTER TABLE ....ACTIVATE NOT LOGGED INITIALLY WITH EMPTY TABLE
    DB2系统内置——SYSCAT.TABLES 所有的字段说明
    DB2系统内置——db2日期和时间常用汇总
    Linux——下查找某个文件位置的方法
    Linux下清除tomcat缓存
  • 原文地址:https://www.cnblogs.com/zeze/p/6253996.html
Copyright © 2011-2022 走看看