今天学习了一下线段树最简单的单点的思想,一开始有点难懂,理解了的话就还好。这两道题本质都差不多,以后有时间可能会更其他线段树的思路分享,这里就先放题目和代码:
HDU1166:题目描述
更新单点,求区间总和
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=50005;
int T,n;
int score[MAXN*2];
void build(int l,int r,int cur)
{
if(l==r){
scanf("%d",&score[cur]);
return;
}
int mid=(l+r)/2;
build(l,mid,cur*2);
build(mid+1,r,cur*2+1);
score[cur]=score[cur*2]+score[cur*2+1];
}
void update(int i,int k,int l,int r,int cur)
{
if(l==r){
score[cur]+=k;
return;
}
int mid=(l+r)/2;
if(i<=mid) update(i,k,l,mid,cur*2);
else update(i,k,mid+1,r,cur*2+1);
score[cur]=score[cur*2]+score[cur*2+1];
}
int query(int ql,int qr,int l,int r,int cur)
{
if(ql<=l&&qr>=r)
return score[cur];
int mid=(l+r)/2;
int num=0;
if(ql<=mid) num+=query(ql,qr,l,mid,cur*2);
if(qr>mid) num+=query(ql,qr,mid+1,r,cur*2+1);
return num;
}
int main()
{
//freopen("hdu1166.txt","r",stdin);
scanf("%d",&T);
while(T)
{
printf("Case %d:\n",T--);
scanf("%d",&n);
build(1,n,1);
char q[6];
int u,v;
while(1){
scanf("%s%d%d",q,&u,&v);
if(q[0]=='E') break;
else if(q[0]=='A') update(u,v,1,n,1);
else if(q[0]=='S') update(u,-v,1,n,1);
else printf("%d\n",query(u,v,1,n,1));
}
}
return 0;
}
HDU1754:题目描述
更新单点,求区间最大值
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=200005;
int n,m;
int score[MAXN*2];
void build(int l,int r,int cur)
{
if(l==r){
scanf("%d",&score[cur]);
return;
}
int mid=(l+r)/2;
build(l,mid,cur*2);
build(mid+1,r,cur*2+1);
score[cur]=max(score[cur*2],score[cur*2+1]);
}
void update(int i,int k,int l,int r,int cur)
{
if(l==r){
score[cur]=k;
return;
}
int mid=(l+r)/2;
if(i<=mid) update(i,k,l,mid,cur*2);
else update(i,k,mid+1,r,cur*2+1);
score[cur]=max(score[cur*2],score[cur*2+1]);
}
int query(int ql,int qr,int l,int r,int cur)
{
if(ql<=l&&qr>=r)
return score[cur];
int mid=(l+r)/2;
int num=0;
if(ql<=mid) num=max(num,query(ql,qr,l,mid,cur*2));
if(qr>mid) num=max(num,query(ql,qr,mid+1,r,cur*2+1));
return num;
}
int main()
{
//freopen("hdu1754.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF)
{
build(1,n,1);
char q[2];
int u,v;
for(int i=0;i<m;i++){
scanf("%s%d%d",q,&u,&v);
if(q[0]=='U') update(u,v,1,n,1);
else printf("%d\n",query(u,v,1,n,1));
}
}
return 0;
}