首页 > 其他分享 >HDU 1166 敌兵布阵(线段树)

HDU 1166 敌兵布阵(线段树)

时间:2023-04-13 23:36:39浏览次数:51  
标签:rt HDU int 线段 ans 1166 sum include 节点


题目地址:HDU 1166

听说胡浩版的线段树挺有名的。于是就拜访了一下他的博客。详情戳这里。于是就完全仿照着胡浩大牛的风格写的代码。

至于原理,鹏鹏学长已经讲的再清晰不过了。我就在下面的代码注释中将原理说明一下吧。来纪念第一发线段树。

下面是代码+注释。


#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <stack>
using namespace std;
#define lson l, mid, rt<<1//直接定义子节点,因为每次都要用到,所以直接定义一个很方便
#define rson mid+1, r, rt<<1 | 1
const int MAXN=51000;
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 mid=(l+r)>>1;
    build(lson);//向左子节点继续建立二叉树
    build(rson);//向右子节点继续建立二叉树
    PushUP(rt);//全部建立完后向上更新父节点的值
}
void update(int p, int x, int l, int r, int rt)//单点修改
{
    if(l==r)//说明已经到了最底端的叶子节点,已经是单点了,可以直接修改该值
    {
        sum[rt]+=x;
        return ;
    }
    int mid=(l+r)>>1;
    if(p<=mid) update(p,x,lson);//如果要修改的值在这个区间左边,就进入左子节点继续寻找
    else update(p,x,rson);//如果要修改的值在这个区间右边,就进入右子节点继续寻找
    PushUP(rt);//修改完后,仍然要向上更新父节点的值
}
int query(int ll, int rr, int l, int r, int rt)//区间查询
{
    if(ll<=l&&rr>=r)//如果要查询的区间完全覆盖了该子节点,直接返回该子节点的值
        return sum[rt];
    int mid=(l+r)>>1;
    int ans=0;
    if(ll<=mid) ans+=query(ll,rr,lson);//如果在该子节点左边还有一部分要查询的区间,就去左子树继续查询
    if(rr>mid) ans+=query(ll,rr,rson);//如果在该子节点右边还有一部分要查询的区间,就去右子树继续查询
    return ans;
}
int main()
{
    int t, n, i, a, b, ans, num=0;
    char s[20];
    scanf("%d",&t);
    while(t--)
    {
        num++;
        printf("Case %d:\n",num);
        memset(sum,0,sizeof(sum));
        scanf("%d",&n);
        build(1,n,1);//建立
        /*for(i=1;i<=25;i++)
        {
            printf("%d    %d\n",i,sum[i]);
        }*/
        getchar();
        while(scanf("%s",s))
        {
            if(s[0]=='E') break;
            if(!strcmp(s,"Add"))
            {
                scanf("%d%d",&a,&b);
                update(a,b,1,n,1);//修改
            }
            else if(!strcmp(s,"Sub"))
            {
                scanf("%d%d",&a,&b);
                update(a,-b,1,n,1); //修改
            }
            else
            {
                scanf("%d%d",&a,&b);
                ans=query(a,b,1,n,1);//查询
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}



标签:rt,HDU,int,线段,ans,1166,sum,include,节点
From: https://blog.51cto.com/u_16070138/6188703

相关文章

  • HDU - 7125 Master of Shuangpin
    D.MasterofShuangpintimelimitpertest1secondmemorylimitpertest256megabytesinputstandardinputoutputstandardoutputAsyouknow,therearethreekindsofChineseinputmethodscommonlyused:Wubi,PinyinandShuangpin.WithShuangpin......
  • HDU 2222 Keywords Search (AC自动机)
    题目地址:HDU2222AC自动机第一发!真好奇这些算法是怎么被发明的。。算法的魅力真是无穷。这题是AC自动机模板题。自己实在写不出来,比着kuangbin的模板写的==代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#incl......
  • HDU 4313 Matrix (贪心)
    题目地址:HDU4313利用最小生成树的思想,这里是从大往下删,能删则删,不能删就留着。用个并查集维护下。代码如下:#include<iostream>#include<string.h>#include<math.h>#include<queue>#include<algorithm>#include<stdlib.h>#include<map>#include<set>......
  • HDU 4628 Pieces (状压DP)
    题目地址:HDU4628这题没想到怎么快速枚举子状态。。。看了题解才知道的。用for(state=i;state>0;state=(state-1)&i)就可以了。这题的具体做法是先预处理出所有的状态是不是回文串,然后就是普通的DP了。代码如下:#include<iostream>#include<string.h>#include<math.h>......
  • HDU 4812 D Tree (树上点分治)
    题目地址:HDU4812这题是13年南京区域赛的现场题。树分治思想。树分治的过程中记录下每个子树的所有到达根的路径的积,用best记录下每个积的最小端点,然后再枚举当前子树的每个积,然后用逆元的方法求出当积为k时所需要的另一个端点值,并更新答案。代码如下:#include<iostream>#......
  • HDU 5145 NPY and girls (莫队分块离线)
    题目地址:HDU5145莫队真的好神奇。。这样的复杂度居然只有n*sqrt(n)。。。裸的莫队分块,先离线,然后按左端点分块,按块数作为第一关键字排序,然后按r值作为第二关键字进行排序。都是从小到大,可以证明这样的复杂度只有n*sqrt(n)。然后进行块之间的转移。代码如下:#include<ios......
  • HDU 5016 Mart Master II (树上点分治)
    题目地址:HDU5016先两遍DFS预处理出每个点距最近的基站的距离与基站的编号。然后找重心,求出每个点距重心的距离,然后根据dis[x]+dis[y]<d[y],用二分找出当前子树中不会被占领的数量,总点数减去即是被占领的数量。这样就可以求出每个点最多占领的点的数量。然后找最大值即可。......
  • ZOJ 3886 Nico Number (线段树)
    题目地址:ZJU3886这个题需要想到一点,因为对一个数x不断取模的话,而且设定他小于模才会进行取余操作的话,那么最多只会进行logx次,因为每次取模都会使x最少折半。然后想到了这点就很好做了。对于区间取模更新操作可以直接暴力更新,维护一个最大值,如果这个区间的最大值小于模的话,就......
  • HDU 1452 Happy 2004 (积性函数)
    题目地址:HDU1452性质1:如果gcd(a,b)=1则S(a*b)=S(a)*S(b)2004^X=4^X*3^X*167^XS(2004^X)=S(2^(2X))*S(3^X)*S(167^X)性质2:如果p是素数则S(p^X)=1+p+p^2+…+p^X=(p^(X+1)-1)/(p-1)因此:S(2004^X)=(2^(2X+1)-1)*(3^(X+1)-1)/2*(167^(X+1)-1)/166......
  • HDU 4864Task(多校联合训练1)(贪心)
    题目地址:HDU4864这题又是一上来认为是最小费用流,但是边太多,果然,敲完交上去后不断TLE。。小优化了两次也没过。。。sad。。后来看了题解才发现是贪心。。。贪心也不好想。大体思路是很好想的,就是先都按时间从大到小排序,再遍历任务,从机器里找能匹配的,并在能匹配的里边找等级尽量小的......