区间求和:
hdu 1166
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
//线段树区间求和:
const int maxn=50005;
int tre[maxn];
struct node
{
int l,r,sum;
}tr[4*maxn];
void build(int i,int l,int r)
{
tr[i].l=l;
tr[i].r=r;
if(l==r)
{
tr[i].sum=tre[l];
return;
}
int mid=(tr[i].l+tr[i].r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tr[i].sum=tr[i*2].sum+tr[i*2+1].sum;
}
void update(int i,int pos,int data)
{
if(tr[i].l==pos&&tr[i].r==pos)
{
tr[i].sum+=data;
return;
}
int mid=(tr[i].l+tr[i].r)/2;
if(pos<=mid) update(i*2,pos,data);
else update(i*2+1,pos,data);
tr[i].sum=tr[i*2].sum+tr[i*2+1].sum;
}
int query(int i,int x,int y)
{
if(x<=tr[i].l&&y>=tr[i].r) /如果这里改为tr[i].l==tr[i].r 将会超时~
return tr[i].sum;
int mid=(tr[i].l+tr[i].r)/2;
int sum=0;
if(y<=mid) sum+=query(i*2,x,y);
else if(x>=mid+1) sum+=query(i*2+1,x,y);
else
{
sum+=query(i*2,x,mid);
sum+=query(i*2+1,mid+1,y);
}
return sum;
}
int main()
{
int T;
int k=1;
cin>>T;
while(T--)
{
printf("Case %d:\n",k++);
char s[20];
int n,x,y;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&tre[i]);
build(1,1,n);
while(1)
{
scanf("%s",s);
if(s[0]=='E') break;
scanf("%d%d",&x,&y);
if(s[0]=='A') update(1,x,y);
if(s[0]=='S') update(1,x,-y);
if(s[0]=='Q') cout<<query(1,x,y)<<endl;
}
}
return 0;
}
区间最大值:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
//线段树区间最大值:
const int maxn=200005;
int tre[maxn];
struct node
{
int l,r;
int maxl;
}tr[4*maxn];
int max(int a,int b)
{
return a>b?a:b;
}
void build(int i,int l,int r)
{
tr[i].l=l;
tr[i].r=r;
if(l==r)
{
tr[i].maxl=tre[l];
return;
}
int mid=(tr[i].l+tr[i].r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tr[i].maxl=max(tr[i*2].maxl,tr[i*2+1].maxl);
}
void update(int i,int pos,int data)
{
if(tr[i].l==tr[i].r)
{
tr[i].maxl=data;
return;
}
int mid=(tr[i].l+tr[i].r)/2;
if(pos<=mid) update(i*2,pos,data);
else update(i*2+1,pos,data);
tr[i].maxl=max(tr[i*2].maxl,tr[i*2+1].maxl);
}
int query(int i,int x,int y)
{
if(x<=tr[i].l&&y>=tr[i].r)
return tr[i].maxl;
int mid=(tr[i].l+tr[i].r)/2;
int maxx=0;
if(y<=mid) maxx=max(maxx,query(i*2,x,y));
else if(x>=mid+1) maxx=max(maxx,query(i*2+1,x,y));
else
{
maxx=max(maxx,query(i*2,x,mid));
maxx=max(maxx,query(i*2+1,mid+1,y));
}
return maxx;
}
int main()
{
int n, m, a, b;
char ch[5];
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
scanf("%d",&tre[i]);
build(1,1,n);
while(m--)
{
getchar();
scanf("%s%d%d",ch, &a, &b);
if(ch[0] == 'Q')
printf("%d\n",query( 1,a, b));
else
update(1,a,b);
}
}
return 0;
}
区间最大值最小值之差:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn=200005;
int tre[maxn];
struct node
{
int l,r;
int maxl,minl;
}tr[4*maxn];
void build(int i,int l,int r)
{
tr[i].l=l;
tr[i].r=r;
if(l==r)
{
tr[i].maxl=tre[l];
tr[i].minl=tre[l];
return;
}
int mid=(tr[i].l+tr[i].r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tr[i].maxl=max(tr[i*2].maxl,tr[i*2+1].maxl);
tr[i].minl=min(tr[i*2].minl,tr[i*2+1].minl);
}
/*void update(int i,int pos,int data)
{
if(tr[i].l==tr[i].r)
{
tr[i].maxl=data;
return;
}
int mid=(tr[i].l+tr[i].r)/2;
if(pos<=mid) update(i*2,pos,data);
else update(i*2+1,pos,data);
tr[i].maxl=max(tr[i*2].maxl,tr[i*2+1].maxl);
}*/
int query1(int i,int x,int y)
{
if(x<=tr[i].l&&y>=tr[i].r)
return tr[i].maxl;
int mid=(tr[i].l+tr[i].r)/2;
int maxx=0;
if(y<=mid) maxx=max(maxx,query1(i*2,x,y));
else if(x>=mid+1) maxx=max(maxx,query1(i*2+1,x,y));
else
{
maxx=max(maxx,query1(i*2,x,mid));
maxx=max(maxx,query1(i*2+1,mid+1,y));
}
return maxx;
}
int query2(int i,int x,int y)
{
if(x<=tr[i].l&&y>=tr[i].r)
return tr[i].minl;
int mid=(tr[i].l+tr[i].r)/2;
int minn=1000005;
if(y<=mid) minn=min(minn,query2(i*2,x,y));
else if(x>=mid+1) minn=min(minn,query2(i*2+1,x,y));
else
{
minn=min(minn,query2(i*2,x,mid));
minn=min(minn,query2(i*2+1,mid+1,y));
}
return minn;
}
int main()
{
int n,m;
while(cin>>n>>m)
{
for(int i=1;i<=n;i++)
scanf("%d",&tre[i]);
build(1,1,n);
while(m--)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",query1(1,x,y)-query2(1,x,y));
}
}
}