hdu1116 敌兵布阵(单点更新+区间查询)
【题意】
每组数据第一行一个正整数N(N<=50000),表示敌人有N个工兵营地,接下来有N个正整数,第i个正整数ai代表第i个工兵营地里开始时有ai个人(1<=ai<=50)。
接下来每行有一条命令,命令有4种形式:
(1) Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;
(4)End 表示结束,这条命令在每组数据最后出现;
【解题思路】
算是一道很模板的模板题了,但是为了熟悉一下树状数组我觉得挑一道模板题里入门还是不错滴。
【代码】
#include<bits/stdc++.h>
using namespace std;
int n,c[50005];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int v)
{
while(x<=n){
c[x]+=v;
x+=lowbit(x);
}
}
int query(int x)
{
int sum=0;
while(x>0){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int T,k=1;
scanf("%d",&T);
while(T--){
memset(c,0,sizeof(c));
char s[10];
scanf("%d",&n);
for(int i=1;i<=n;i++){
int t;
scanf("%d",&t);
add(i,t);
}
printf("Case %d:\n",k++);
while(~scanf("%s",s) && s[0]!='E'){
int x,y;
scanf("%d%d",&x,&y);
if(s[0]=='A'){
add(x,y);
}
else if(s[0]=='S'){
add(x,-y);
}
else if(s[0]=='Q'){
printf("%d\n",query(y)-query(x-1));
}
}
}
return 0;
}
zcmu1156 新年彩灯Ⅰ(区间更新+单点查询)
【题意】
YY准备挂一排彩灯,已知彩灯刚挂完的彩灯共有N盏(编号为1,2,3,……),并且都是灭的。彩灯的闪烁由一段程序控制。每一秒钟程序会生成两个正整数a和b(1<=a,b<=N),然后将编号为a和b之间的所有灯的状态改变一次。
然后是M行数据,包括以下两种形式:
1 a b 表示灯a和灯b之间的灯(含灯a和灯b)变换一次状态。
0 x y 表示YY想知道此刻灯x到灯y(包含灯x和灯y)的状态。
【解题思路】
每对灯进行一次操作就将该区间内的灯+1,稍微模拟一下就能发现,当灯为偶数时,其实就是熄灭的状态,奇数则是亮着的。
然后这里要注意一下a,b的位置是不确定的,当b<a的时候记得swap。
【代码】
#include<bits/stdc++.h>
using namespace std;
int n,c[1000005];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int v)
{
while(x<=n){
c[x]+=v;
x+=lowbit(x);
}
}
int query(int x)
{
int sum=0;
while(x){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void range_update(int x,int y,int t)
{
add(x,t);
add(y+1,-t);
}
int main()
{
int m;
while(~scanf("%d%d",&n,&m)){
memset(c,0,sizeof(c));
int p,a,b;
while(m--){
scanf("%d%d%d",&p,&a,&b);
if(b<a)swap(a,b);
if(p==1)update(a,b,1);
else{
for(int i=a;i<=b;i++){
int t=query(i);
if(t%2)printf("1");
else printf("0");
}
printf("\n");
}
}
}
return 0;
}
洛谷3368 【模板】树状数组2(区间查询+单点更新)
【题意】
如题,已知一个数列,你需要进行下面两种操作:
1.将某区间每一个数数加上x
2.求出某一个数的和
【解题思路】
就是套模板啦~目前树状数组只会套模板的我qaq因为是区间查询,记得将c数组变成差分数组
【代码】
#include<bits/stdc++.h>
using namespace std;
int n,c[500005];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int v)
{
while(x<=n){
c[x]+=v;
x+=lowbit(x);
}
}
int ask(int x)
{
int sum=0;
while(x>0){
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void range_update(int a,int b,int v)
{
update(a,v);
update(b+1,-v);
}
int main()
{
int m,x,t=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&x);
update(i,x-t);
t=x;
}
while(m--){
int p;
scanf("%d",&p);
if(p==1){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
range_update(a,b,c);
}
else if(p==2){
int c;
scanf("%d",&x);
printf("%d\n",ask(x));
}
}
return 0;
}