我做过的几种线段树类型,贴一下代码备忘
1.HDU1166 更新节点,区间求和
#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXN 100005
struct node
{
int begin,end;
int value;
};
node ST[MAXN*2];
int N,A[MAXN];
int initST(int cur,int begin,int end)
{
int mid=(begin+end)/2;
ST[cur].begin=begin;
ST[cur].end=end;
if(begin==end)
{
return ST[cur].value=A[begin];
}else
{
return ST[cur].value=initST(cur<<1,begin,mid)+initST(cur<<1|1,mid+1,end);
}
}
int Query(int cur,int a,int b)
{
int mid=(ST[cur].begin+ST[cur].end)/2;
if(a==ST[cur].begin && b==ST[cur].end)
{
return ST[cur].value;
}
if(a>mid)
return Query(cur<<1|1,a,b);
if(b<=mid)
return Query(cur<<1,a,b);
return Query(cur<<1,a,mid)+Query(cur<<1|1,mid+1,b);
}
void Add(int cur,int pos,int num)
{
ST[cur].value+=num;
if(ST[cur].begin==ST[cur].end)
return;
if(pos<=(ST[cur].begin+ST[cur].end)/2)
Add(cur<<1,pos,num);
else
Add(cur<<1|1,pos,num);
}
void Sub(int cur,int pos,int num)
{
ST[cur].value-=num;
if(ST[cur].begin==ST[cur].end)
return;
if(pos<=(ST[cur].begin+ST[cur].end)/2)
Sub(cur<<1,pos,num);
else
Sub(cur<<1|1,pos,num);
}
int main()
{
int n,i,j,a,b;
string s;
cin>>n;
for(i=0;i<n;++i)
{
cin>>N;
memset(ST,0,sizeof(ST));
for(j=0;j<N;++j)
{
cin>>A[j];
}
initST(1,0,N-1);
cout<<"Case "<<i+1<<":"<<endl;
while(cin>>s,s!="End")
{
if(s=="Query")
{
cin>>a>>b;
cout<<Query(1,a-1,b-1)<<endl;
}else if(s=="Add")
{
cin>>a>>b;
Add(1,a-1,b);
}else if(s=="Sub")
{
cin>>a>>b;
Sub(1,a-1,b);
}
}
}
}
2.HDU1754 更新节点,区间最值
#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXN 200900
struct node
{
int begin,end;
int value;
};
int Max(const int &a,const int &b)
{
return a>b?a:b;
}
node ST[MAXN*3];
int N,A[MAXN];
int initST(int cur,int begin,int end)
{
int mid=(begin+end)/2;
ST[cur].begin=begin;
ST[cur].end=end;
if(begin==end)
{
return ST[cur].value=A[begin];
}else
{
return ST[cur].value=Max(initST(cur<<1,begin,mid),initST(cur<<1|1,mid+1,end));
}
}
int Query(int cur,int a,int b)
{
int mid=(ST[cur].begin+ST[cur].end)/2;
if(a==ST[cur].begin && b==ST[cur].end)
{
return ST[cur].value;
}
if(a>mid)
return Query(cur<<1|1,a,b);
if(b<=mid)
return Query(cur<<1,a,b);
return Max(Query(cur<<1,a,mid),Query(cur<<1|1,mid+1,b));
}
int Update(int cur,int pos,int num)
{
if(ST[cur].begin==ST[cur].end)
{
ST[cur].value=num;
return num;
}
if(pos<=(ST[cur].begin+ST[cur].end)/2)
{
int r=Update(cur<<1,pos,num);
ST[cur].value=Max(r,ST[cur<<1|1].value);
return ST[cur].value;
}
else
{
int r=Update(cur<<1|1,pos,num);
ST[cur].value=Max(r,ST[cur<<1].value);
return ST[cur].value;
}
}
int main()
{
int n,i,j,a,b,M;
char c;
while(cin>>N>>M)
{
memset(ST,0,sizeof(ST));
for(j=0;j<N;++j)
{
scanf("%d",A+j);
}
initST(1,0,N-1);
for(j=0;j<M;++j)
{
scanf("%*[ \n]%c%d%d",&c,&a,&b);
if(c=='Q')
{
printf("%d\n",Query(1,a-1,b-1));
}else
{
Update(1,a-1,b);
}
}
}
}
3.HDU1698 成段更新
#include <cstdio>
#include <iostream>
using namespace std;
#define MAXN 200005
#define LL(x) ((x)<<1)
#define RR(x) ((x)<<1|1)
struct node
{
int begin,end;
int value;
};
node ST[MAXN*2+1];
int N,A[MAXN];
int Q;
void initST(int cur,int begin,int end)
{
int mid=(begin+end)/2;
ST[cur].begin=begin;
ST[cur].end=end;
//ST[cur].value=1;
if(begin==end)
{
return;
}
initST(cur<<1,begin,mid);
initST(cur<<1|1,mid+1,end);
}
void Update(int cur,int begin,int end,int value)
{
if (ST[cur].begin>end || ST[cur].end<begin)
{
return ;
}
if(begin<=ST[cur].begin && ST[cur].end<=end)
{
ST[cur].value=value;
return;
}
if(ST[cur].value==value)
return;
if(ST[cur].value!=-1)
ST[LL(cur)].value=ST[RR(cur)].value=ST[cur].value;
ST[cur].value=-1;
Update(LL(cur),begin,end,value);
Update(RR(cur),begin,end,value);
}
int Query(int cur,int begin,int end)
{
if (ST[cur].begin>end || ST[cur].end<begin)
{
return 0;
}
if (ST[cur].value == -1)
{
return Query(LL(cur),begin,end)+Query(RR(cur),begin,end);
}
int maxleft=begin>ST[cur].begin?begin:ST[cur].begin;
int minright=end<ST[cur].end?end:ST[cur].end;
return ST[cur].value*(minright-maxleft+1);
}
void print()
{
int i,j=0,index=1;
for (i=1;i<=N;i*=2)
{
for (j=0;j<i;++j)
{
cout<<ST[index++].value<<" ";
}
cout<<endl;
}
}
int solve()
{
int a,b,v,j;
scanf("%d%d",&N,&Q);
initST(1,0,N-1);
ST[1].value=1;
for(j=0;j<Q;++j)
{
scanf("%d%d%d",&a,&b,&v);
Update(1,a-1,b-1,v);
//print();
}
return Query(1,0,N-1);
}
int main()
{
int n,i;
scanf("%d",&n);
for(i=0;i<n;++i)
{
cout<<"Case "<<i+1<<": The total value of the hook is "<<solve()<<"."<<endl;
}
return 0;
}
4.HDU1394 更新节点求区间和
#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXN 10000
struct node
{
int begin,end;
int value;
};
node ST[MAXN*2];
int N,A[MAXN],B[MAXN];
int initST(int cur,int begin,int end)
{
int mid=(begin+end)>>1;
ST[cur].begin=begin;
ST[cur].end=end;
if(begin==end)
{
return ST[cur].value=A[begin];
}else
{
return ST[cur].value=initST(cur<<1,begin,mid)+initST(cur<<1|1,mid+1,end);
}
}
int Query(int cur,int a,int b)
{
int mid=(ST[cur].begin+ST[cur].end)>>1;
if(a==ST[cur].begin && b==ST[cur].end)
{
return ST[cur].value;
}
if(a>mid)
return Query(cur<<1|1,a,b);
if(b<=mid)
return Query(cur<<1,a,b);
return Query(cur<<1,a,mid)+Query(cur<<1|1,mid+1,b);
}
void Add(int cur,int pos,int num)
{
ST[cur].value+=num;
if(ST[cur].begin==ST[cur].end)
return;
if(pos<=((ST[cur].begin+ST[cur].end)>>1))
Add(cur<<1,pos,num);
else
Add(cur<<1|1,pos,num);
}
void Sub(int cur,int pos,int num)
{
ST[cur].value-=num;
if(ST[cur].begin==ST[cur].end)
return;
if(pos<=((ST[cur].begin+ST[cur].end)>>1))
Sub(cur<<1,pos,num);
else
Sub(cur<<1|1,pos,num);
}
int main()
{
int n,i,j,a,b;
string s;
while(cin>>N)
{
memset(ST,0,sizeof(ST));
//memset(A,0,sizeof(A));
initST(1,0,N-1);
int sum=0;
for(j=0;j<N;++j)
{
int num;
//cin>>num;
scanf("%d",&num);
B[j]=num;
Add(1,num,1);
if(num<N-1) sum+=Query(1,num+1,N-1);
}
int minn=sum;
for (j=0;j<N;++j)
{
sum=sum+N-B[j]*2-1;
if (sum<minn)
{
minn=sum;
}
}
cout<<minn<<endl;
}
}
5.POJ3468 更新区间,区间求和
#include <iostream>
#include <string>
#include <string.h>
#include <stdio.h>
using namespace std;
#define MAXN 100005
struct node
{
int begin,end;
__int64 value;
__int64 add;
};
node ST[MAXN*4];
int N,A[MAXN],Q;
__int64 initST(int cur,int begin,int end)
{
int mid=(begin+end)>>1;
ST[cur].begin=begin;
ST[cur].end=end;
if(begin==end)
{
return ST[cur].value=A[begin];
}else
{
return ST[cur].value=initST(cur<<1,begin,mid)+initST(cur<<1|1,mid+1,end);
}
}
__int64 Query(int cur,int pos1,int pos2)
{
int mid=(ST[cur].begin+ST[cur].end)>>1;
if(pos1<=ST[cur].begin && ST[cur].end<=pos2)
{
return ST[cur].value+ST[cur].add*(ST[cur].end-ST[cur].begin+1);
}
if (ST[cur].add)
{
ST[cur].value+=ST[cur].add*(ST[cur].end-ST[cur].begin+1);
ST[cur<<1].add+=ST[cur].add;
ST[cur<<1|1].add+=ST[cur].add;
ST[cur].add=0;
}
if(pos1>mid)
return Query(cur<<1|1,pos1,pos2);
if(pos2<=mid)
return Query(cur<<1,pos1,pos2);
return Query(cur<<1,pos1,mid)+Query(cur<<1|1,mid+1,pos2);
}
void print()
{
int i,j;
int k=1;
for(i=1;i<=N;i*=2)
{
for (j=0;j<i;++j)
{
printf(" %d(%d)",ST[k].value,ST[k].add);
k++;
}
printf("\n");
}
}
void Add(int cur,int pos1,int pos2,int num)
{
if(pos1<=ST[cur].begin && ST[cur].end<=pos2)
{
//ST[cur].value+=num*(ST[cur].end-ST[cur].begin+1);
ST[cur].add+=num;
return;
}
if (ST[cur].add)
{
ST[cur].value+=ST[cur].add*(ST[cur].end-ST[cur].begin+1);
ST[cur<<1].add+=ST[cur].add;
ST[cur<<1|1].add+=ST[cur].add;
ST[cur].add=0;
}
int a=((pos1>ST[cur].begin)?pos1:ST[cur].begin);
int b=((ST[cur].end<pos2)?ST[cur].end:pos2);
ST[cur].value+=num*(b-a+1);
int mid=(ST[cur].begin+ST[cur].end)>>1;
if (pos2>mid)
Add(cur<<1|1,pos1,pos2,num);
if (pos1<=mid)
Add(cur<<1,pos1,pos2,num);
}
int main()
{
int n,i,a,b,c;
char s;
scanf("%d%d",&N,&Q);
for(i=0;i<N;++i)
{
scanf("%d",A+i);
}
initST(1,0,N-1);
for (i=0;i<Q;++i)
{
scanf("%*[ \n]%c",&s);
if(s=='Q')
{
scanf("%d%d",&a,&b);
printf("%I64d\n",Query(1,a-1,b-1));
}else
{
scanf("%d%d%d",&a,&b,&c);
Add(1,a-1,b-1,c);
}
//print();
}
}