zoukankan      html  css  js  c++  java
  • hdu 1541 Stars(线段树单点更新,区间查询)

    题意:求坐标0到x间的点的个数

    思路:线段树,主要是转化,根据题意的输入顺序,保证了等级的升序,可以直接求出和即当前等级的点的个数,然后在把这个点加入即可。

    注意:线段树下标从1开始,所以把所有的x加1存储。

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    using namespace std;
    
    #define MAXN 32005
    #define MAXL 15005
    int ans;
    int lev[MAXL];
    
    struct node{
        int left,right,sum;
        int mid(){
            return (left+right)>>1;
        }
    }tree[MAXN*4];//注意范围,4倍空间
    
    void btree(int left,int right,int rt){//建树
        tree[rt].left=left;
        tree[rt].right=right;
        if(left==right){
            //scanf("%d",&tree[rt].sum);
            tree[rt].sum=0;
            return;
        }
        int mid=tree[rt].mid();
        btree(left,mid,rt<<1);
        btree(mid+1,right,rt<<1|1);
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;//区间里的点数=左区间+右区间
    }
    
    void query(int left,int right,int rt,int L,int R){//询问求和
        if(L<=left&&right<=R){
            ans+=tree[rt].sum;
            return;
        }
        int mid=tree[rt].mid();
        if(R<=mid)query(left,mid,rt<<1,L,R);//区间在左子树
        else if(L>mid)query(mid+1,right,rt<<1|1,L,R);//区间在右子树
        else{
            query(left,mid,rt<<1,L,R);
            query(mid+1,right,rt<<1|1,L,R);
        }
    }
    
    void update(int left,int right,int rt,int pos,int add){//单点更新函数
        if(left==right){
            tree[rt].sum+=add;
            return;
        }
        int mid=tree[rt].mid();
        if(pos<=mid)update(left,mid,rt<<1,pos,add);//点在左子树
        else update(mid+1,right,rt<<1|1,pos,add);//点在右子树
        tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;//区间和更新
    }
    
    int main(){
        int n,x,y,i;
        while(~scanf("%d",&n)){
            btree(1,MAXN,1);
            memset(lev,0,sizeof(lev));
            for(i=0;i<n;++i){
                scanf("%d%d",&x,&y);
                ++x;//线段树从1开始
                ans=0;
                query(1,MAXN-1,1,1,x);
                ++lev[ans];//先求和
                update(1,MAXN-1,1,x,1);//后加1
            }
            for(i=0;i<n;++i)
                printf("%d
    ",lev[i]);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    《C++ 并发编程》- 第1章 你好,C++的并发世界
    30分钟,让你成为一个更好的程序员
    程序员技术练级攻略
    谈新技术学习方法-如何学习一门新技术新编程语言
    计算机科学中最重要的32个算法
    程序员学习能力提升三要素
    一位在MIT教数学的老师总结了十条经验
    学习算法之路
    十个顶级的C语言资源助你成为优秀的程序员
    Linux中LoadAverage分析
  • 原文地址:https://www.cnblogs.com/gongpixin/p/4739084.html
Copyright © 2011-2022 走看看