首页 > 其他分享 >「HDU1166」敌兵布阵

「HDU1166」敌兵布阵

时间:2023-08-22 17:22:22浏览次数:40  
标签:right int segment mid 敌兵 HDU1166 root 布阵 left

前言

题目好多废话

大意

有一个序列,开始时每一位都有一个值,然后是若干个命令:

  1. Add i j,表示第\(i\)位增加\(j\);
  2. Sub i j,表示第\(i\)位减少\(j\);
  3. Query i j,表示从第\(i\)位到地\(j\)位的总和;
  4. End,表示结束,在每组数据最后出现。

思路

这题一眼盯真,可以用线段树或者树状数组解决,都是单点修改,区间查询,然后直接套模板就行了。

\(Code\)

线段树:

#include<bits/stdc++.h>
char q[10];
int t,tot,n,v1,v2,segment[200005];
inline void pushUp(int root){segment[root]=segment[root*2]+segment[root*2+1];}
inline void built(int root,int left,int right){if(left==right){scanf("%d",&segment[root]);return;}int mid=(left+right)/2;built(root*2,left,mid);built(root*2+1,mid+1,right);pushUp(root);}
inline void update(int root,int pos,int add_num,int left,int right){if(left==right){segment[root]+=add_num;return;}int mid=(left+right)/2;if(pos<=mid)update(root*2,pos,add_num,left,mid);else update(root*2+1,pos,add_num,mid+1,right);pushUp(root);}//更新
inline int sum(int root,int left,int right,int L,int R){if(left==L&&right==R)return segment[root];int mid=(L+R)/2,res=0;if(left>mid)res+=sum(root*2+1,left,right,mid+1,R);else if(right<=mid)res+=sum(root*2,left,right,L,mid);else res+=sum(root*2,left,mid,L,mid)+sum(root*2+1,mid+1,right,mid+1,R);return res;}//求和
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		built(1,1,n);//建树
		printf("Case %d:\n",++tot);
		while(scanf("%s",q)){
			if(q[0]=='E')break;
			scanf("%d%d",&v1,&v2);
			if(q[0]=='A')update(1,v1,v2,1,n);//单点修改
			else if(q[0]=='S')update(1,v1,-v2,1,n);//单点修改
			else printf("%d\n",sum(1,v1,v2,1,n));//区间查询
		}
	}
}

树状数组:

#include<bits/stdc++.h>
int t,tot,v1,v2,a[50005],n;
char q[8];
int lowbit(int i){return i&-i;}
inline void update(int i, int v){while(i<=n)a[i]+=v,i+=lowbit(i);}//更新
inline int sum(int i){int sum=0;while(i>0)sum+=a[i],i-=lowbit(i);return sum;}//求和
int main(){
	scanf("%d",&t);
	while(t--){
		memset(a,0,sizeof(a));//初始化
		scanf("%d",&n);
		for(int i=1;i<=n;++i){
			scanf("%d",&v1);
			update(i,v1);//初始值
		}
		printf("Case %d:\n",++tot);
		while(~scanf("%s",q)){
			if(q[0]=='E')break;
			scanf("%d%d",&v1,&v2);
			if(q[0]=='A')update(v1,v2);//单点修改
			else if(q[0]=='S')update(v1,-v2);//单点修改
			else if(q[0]=='Q')printf("%d\n",sum(v2)-sum(v1-1));//区间查询
		}
	}
}

标签:right,int,segment,mid,敌兵,HDU1166,root,布阵,left
From: https://www.cnblogs.com/z10h09x11/p/17649130.html

相关文章

  • 洛谷P5322 [BJOI2019] 排兵布阵
    题目大意有s名对手,n座城堡,你有m名士兵如果一名玩家向第\(i\)座城堡派遣的士兵数严格大于对手派遣士兵数的两倍,那么这名玩家就占领了这座城堡,获得\(i\)分。求最大得分数据范围对于\(10\%\)的数据:\(s=1,n\le3,m\le10\)对于\(20\%\)的数据:\(s=1,n\le10,m\le1......
  • 树状数组讲解与例题 杭电HDU1166,HDU1556,HDU2689
    树状数组的总结树状数组很巧妙地解决了数列的求和与查找,速度很快。树状数组,它改变数列中某一位,或者求某个区间的和,时间复杂度是O(logN);效率大为改善。下面的图片很好的演示了树状数组的存储原理。(图片来自网络)观察图片,会发现:数组c的每一个元素都管辖着一定范围内的数组a元素的和,比如C......
  • P5322 BJOI2019 排兵布阵
    P5322BJOI2019排兵布阵本题主要考察对模型的转化能力。首先要察觉两条性质:对于一个城堡,想打败一个玩家的同时用最少的士兵,肯定是正好派出这个玩家在这个城堡派出的士兵数量的二倍加一名士兵。在一个城堡上,打败了一个在这个城堡派出士兵数量为\(x\)的玩家,就可以顺便打败所......
  • HDU 1166 敌兵布阵(线段树)
    题目地址:HDU1166听说胡浩版的线段树挺有名的。于是就拜访了一下他的博客。详情戳这里。于是就完全仿照着胡浩大牛的风格写的代码。至于原理,鹏鹏学长已经讲的再清晰不过了。我就在下面的代码注释中将原理说明一下吧。来纪念第一发线段树。下面是代码+注释。#include<iostream>#in......
  • P5322 [BJOI2019] 排兵布阵
     小C正在玩一款排兵布阵的游戏。在游戏中有nn座城堡,每局对战由两名玩家来争夺这些城堡。每名玩家有m名士兵,可以向第ii座城堡派遣ai名士兵去争夺这个城堡,使得总......
  • 敌兵布阵
    敌兵布阵TimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):67477    AcceptedSubmission(s):2837......
  • 各种不同几何形状布局布阵下的GDOP相对值图matlab仿真
    1.算法描述        全球四大导航卫星系统包括:美国GPS、俄罗斯GLONASS(格洛纳斯)、中国北斗和欧洲Galileo(伽利略)卫星系统。四大卫星定位系统靠卫星自身可以达到......
  • hdu:敌兵布阵(树状数组)
    ProblemDescriptionC国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就......