HDU 1166 敌兵布阵
2017-04-14 19:03
204 查看
敌兵布阵
题目链接:点击打开链接题目和本博客里之前的题目没什么区别,都是典型的树状数组增删改查。
代码如下:
#include<stdio.h> #include<string.h> #define MAXN 50005 int tree[MAXN]; int data[MAXN]; void add(int x,int num) { for(int i=x;i<MAXN;i+=i&(-i)) tree[i]+=num; } int read(int x) { int sum=0; for(int i=x;i>0;i-=i&(-i)) sum+=tree[i]; return sum; } void A() { int x,num; scanf("%d%d",&x,&num); x++; add(x,num); } void S() { int x,num; scanf("%d%d",&x,&num); x++; add(x,-num); } void Q() { int x,y; scanf("%d%d",&x,&y); x++;y++; int sum=read(y)-read(x-1); printf("%d\n",sum); } int main() { int t,n; int index=1; char str[10]; scanf("%d",&t); while(t--) { memset(tree,0,sizeof(tree)); scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d",&data[i]); add(i+2,data[i]); } printf("Case %d:\n",index++); while(scanf("%s",&str)) { if(str[0]=='A') A(); else if(str[0]=='S') S(); else if(str[0]=='Q') Q(); else if(str[0]=='E') break; } } return 0; }
2017/9/27 加入线段树模板代码:
#include<iostream>
#include<cstdio>
using namespace std;
//(0)定义
#define maxn 100007 //元素的总个数
#define ls,l,m,rt<<1
#define rs m+1,r,rt<<1|1
void PushDown(int rt,int ln,int rn);//声明
void Update(int L,int C,int l,int r,int rt);
int Sum[maxn<<2],Add[maxn<<2]; //Sum构成线段树,Add为懒惰数组
int n,A[maxn]; //原数组下标[1,n];
//(1)建树
void PushUp(int rt) {Sum[rt]=Sum[rt<<1]+Sum[rt<<1|1];}
void Build(int l,int r,int rt)//l,r表示当前结点区间,rt当前节点编号
{
if(l==r){
Sum[rt]=A[l];
return ;
}
int m=(l+r)>>1;
Build(l,m,rt<<1);
Build(m+1,r,rt<<1|1);
PushUp(rt);
}
//(2)点修改
void Update(int L,int C,int l,int r,int rt)//l,r表示当前节点区间,rt表示当前节点编号
{
if(l==r){
Sum[rt]+=C;
return ;
}
int m=(l+r)>>1;
if(L<=m) Update(L,C,l,m,rt<<1);
else Update(L,C,m+1,r,rt<<1|1);
PushUp(rt);
}
void Update(int L,int R,int C,int l,int r,int rt)
{
if(L<=l && r<=R){
Sum[rt]+=C*(r-l+1);
Add[rt]+=C;
return ;
}
int m=(l+r)>>1;
PushDown(rt,m-l+1,r-m);
if(L<=m) Update(L,R,C,l,m,rt<<1);
if(R>m) Update(L,R,C,m+1,r,rt<<1|1);
PushUp(rt);
}
void PushDown(int rt,int ln,int rn)
{//ln,rn为左子树,右子树的数字数量。
if(Add[rt])
{//下推标记
Add[rt<<1]+=Add[rt];
Add[rt<<1|1]=Add[rt];
Sum[rt<<1]+=Add[rt]*ln;
Sum[rt<<1|1]+=Add[rt]*rn;
Add[rt]=0; //清除标记
}
}
int Query(int L,int R,int l,int r,int rt){//L,R表示操作区间,l,r表示当前节点区间,rt表示当前节点编号
if(L <= l && r <= R){
//在区间内,直接返回
return Sum[rt];
}
int m=(l+r)>>1;
//下推标记,否则Sum可能不正确
PushDown(rt,m-l+1,r-m);
//累计答案
int ANS=0;
if(L <= m) ANS+=Query(L,R,l,m,rt<<1);
if(R > m) ANS+=Query(L,R,m+1,r,rt<<1|1);
return ANS;
}
int main()
{
int L,R,C,n,t;
char str[15];
int l,r,inde;
inde=0;
scanf("%d",&t);
while(t--)
{
printf("Case %d:\n",++inde);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&A[i]);
Build(1,n,1);//建树
while(1)
{
scanf("%s",&str);
if(str[0]=='E')
break;
else{
scanf("%d%d",&l,&r);
if(str[0]=='A')
Update(l,r,1,n,1);//点修改
else if(str[0]=='S')
Update(l,-r,1,n,1);//点修改
else{
int ANS=Query(l,r,1,n,1);//区间查询
printf("%d\n",ANS);
}
}
}
}
// Build(1,n,1);//建树
// Update(L,C,1,n,1);//点修改
// Update(L,R,C,1,n,1);//区间修改
// int ANS=Query(L,R,1,n,1);//区间查询
return 0;
}
相关文章推荐
- hdu1166 敌兵布阵
- HDU 1166 敌兵布阵(树状数组)
- HDU 1166 敌兵布阵
- hdu 1166 敌兵布阵(修改点)
- HDU-1166 敌兵布阵 ( 线段树 )
- 敌兵布阵 hdu 1166
- HDU 1166敌兵布阵
- HDU 1166 敌兵布阵(2)
- HDU 1166 敌兵布阵 (线段树 插点问线)
- hdu 1166 敌兵布阵 线段树&树状数组
- HDU 1166 敌兵布阵(线段树)
- HDU 1166 - 敌兵布阵(树状数组)
- HDOJ 1166 HDU 1166 敌兵布阵 ACM 1166 IN HDU
- HDU 1166 敌兵布阵(单点更新)
- 线段树-HDU 1166 敌兵布阵
- HDU 1166 敌兵布阵【线段树】
- [ACM] hdu 1166 敌兵布阵 (线段树,单点更新)
- hdu1166敌兵布阵(线段树)
- HDU 1166 敌兵布阵 // 线段树
- hdu 1166 敌兵布阵