题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1166
代码注释:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
int arr[50100]={0};
int tree[MAX_len];
void build_tree(int node,int start,int end)//建树
{
if(start==end)
{
tree[node]=arr[start];
}
else
{
int mid=(start+end)/2;
int left_node=2*node+1;
int right_node=2*node+2;
build_tree(left_node,start,mid);
build_tree(right_node,mid+1,end);
tree[node]=tree[left_node]+tree[right_node];
}
}
void update_tree(int node ,int start ,int end ,int idx,int val)//单点更新以及区间
{
if(start==end)
{
arr[idx]+=val;
tree[node]+=val;
}
else
{
int mid=(start+end)/2;
int left_node =2*node+1;
int right_node=2*node+2;
if(idx>=start&&idx<=mid)
{
update_tree(left_node,start,mid,idx,val);
}
else
{
update_tree(right_node,mid+1,end,idx,val);
}
tree[node]=tree[left_node]+tree[right_node];
}
}
int query_tree(int node,int start,int end,int L,int R)//查询
{
if(R<start||L>end)
{
return 0;
}
else if(L<=start&&R>=end)
{
return tree[node];
}
else if(start==end)
{
return tree[node];
}
else
{
int mid=(start+end)/2;
int left_node=2*node+1;
int right_node=2*node+2;
int sum_left=query_tree(left_node,start,mid,L,R);
int sum_right=query_tree(right_node,mid+1,end,L,R);
return sum_left+sum_right;
}
}
int main()
{
int T,hh=1;;
scanf("%d",&T);
while(T--)
{
memset(tree,0,sizeof(tree));
printf("Case %d:\n",hh++);
int n,i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
build_tree(0,0,n-1);
char ss[10];
while(scanf("%s",ss)&&strcmp(ss,"End")!=0)
{
int a,b;
scanf("%d %d",&a,&b);
if(strcmp(ss,"Query")==0)
{
printf("%d\n",query_tree(0,0,n-1,a-1,b-1));
continue;
}
if(strcmp(ss,"Add")==0)
{
update_tree(0,0,n-1,a-1,b);
continue;
}
if(strcmp(ss,"Sub")==0)
{
update_tree(0,0,n-1,a-1,-b);//减少的话传入负数即可
continue;
}
}
}
return 0;
}
题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1556
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<queue>
#define MAX_len 400040
using namespace std;
typedef long long ll;
struct A{
int left;
int right;
int sum;
}t[MAX_len];
void build_tree(int l,int r,int node)
{
t[node].left=l,t[node].right=r,t[node].sum=0;
if(l==r)
{
return ;
}
int mid=(l+r)/2;
build_tree(l,mid,node*2);
build_tree(mid+1,r,node*2+1);
}
void update_tree(int l,int r,int node)
{
int mid=(t[node].left+t[node].right)/2;
if(t[node].left==l&&t[node].right==r)
t[node].sum++;
else if(r<=mid)
update_tree(l,r,node*2);
else if(l>mid)
update_tree(l,r,node*2+1);
else
update_tree(l,mid,node*2),update_tree(mid+1,r,node*2+1);
}
int query_tree(int l,int r,int node)
{
int mid=(t[node].right+t[node].left)/2;
if(t[node].left==l&&t[node].right==r)
return t[node].sum;
int ans=0;
if(l>=t[node].left&&r<=t[node].right)
{
ans+=t[node].sum;
if(r<=mid)
ans+=query_tree(l,r,node*2);
else if(l>mid)
ans+=query_tree(l,r,node*2+1);
else
ans+=query_tree(1,mid,node*2)+query_tree(mid+1,r,node*2+1);
}
return ans;
}
int main()
{
int arr[100010]={0};
int tree[MAX_len];
int N;
while(scanf("%d",&N)&&N)
{
build_tree(1,N,1);
int i,j,k,a,b;
for(i=1;i<=N;i++)
{
scanf("%d %d",&a,&b);
update_tree(a,b,1);
}
for(i=1;i<N;i++)
printf("%d ",query_tree(i,i,1));
printf("%d\n",query_tree(N,N,1));
}
return 0;
}