最近学习了好久的线段树,对线段树有了初步的基础的认知,为了巩固知识点找几道基础题练练手转存失败重新上传取消
1.hdu1166 敌兵布阵
http://acm.hdu.edu.cn/showproblem.php?pid=1166
思路:线段树基础模版题(点修改+区间查询)
#include
#include
#include
using namespace std;
typedef long long ll;
const int maxn=50009;
ll a[maxn];
ll sum[maxn*4];
ll Add[maxn*4];
void getup(int x){
sum[x]=sum[x*2]+sum[x*2+1];
return ;
}
void btree(int left,int right,int root)//递归建树
{
if(left==right){
sum[root]=a[left];
return ;
}
int mid=(left+right)/2;
btree(left,mid,root*2);
btree(mid+1,right,root*2+1);
getup(root);
}
/*void pushdown(int rt,int ln,int rn){//区间修改时的标记,本题未用到
if(Add[rt]){
Add[rt*2]+=Add[rt];
Add[rt*2+1]+=Add[rt];
sum[rt*2]+=Add[rt]*ln;
sum[rt*2+1]+=Add[rt]*rn;
Add[rt]=0;
}
}*/
ll myquery(int L,int R,int l,int r,int rt)//区间查询
{
if(L<=l&&r<=R)
return sum[rt];
int mid=(l+r)/2;
//pushdown(rt,mid-l+1,r-mid);
ll ans=0;
if(L<=mid)
ans+=myquery(L,R,l,mid,rt*2);
if(R>mid)
ans+=myquery(L,R,mid+1,r,rt*2+1);
return ans;
}
void addt(int L,int C,int l,int r,int rt)//点修改
{
if(l==r){
sum[rt]+=C;
return;
}
int mid=(l+r)>>1;
if(L<=mid)
addt(L,C,l,mid,rt*2);
else
addt(L,C,mid+1,r,rt*2+1);
getup(rt);
}
int main()
{
int T;
scanf("%d\n",&T);
for(int kk=1;kk<=T;kk++)
{
int N;
scanf("%d\n",&N);
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
btree(1,N,1);
char opt[5];
int num1,num2;
printf("Case %d:\n",kk);
while(scanf("%s",opt)&&opt[0]!='E'){
scanf("%d %d",&num1,&num2);
if(opt[0]=='Q')
printf("%lld\n",myquery(num1,num2,1,N,1));
else if(opt[0]=='A')
addt(num1,num2,1,N,1);
else if(opt[0]=='S')
addt(num1,-1*num2,1,N,1);
}
}
return 0;
}
http://acm.hdu.edu.cn/showproblem.php?pid=1754
思路:线段树+点修改+区间查询
如果用递归写,MLT,改非递归,AC
ac代码
非递归线段树
#include
#include
using namespace std;
typedef long long ll;
const ll maxn=200005;
ll Max[maxn*4];
ll a[maxn];
ll N,m,n;
void btree(int x)
{
N=1;
while(N0;i--)
{
Max[i]=max(Max[i*2],Max[i*2+1]);
}
}
ll query(int l,int r)
{
ll ans=0;
for(int s=N+l-1,t=N+r+1;s^t^1;s/=2,t/=2)
{
if(~s&1) ans=max(ans,Max[s^1]);
if(t&1) ans=max(ans,Max[t^1]);
}
return ans;
}
void update(int L,int C)
{
Max[N+L]=C;
for(int i=(N+L)>>1;i;i>>=1)
{
Max[i]=max(Max[i<<1],Max[i<<1|1]);
}
}
int main()
{
while(scanf("%lld %lld",&n,&m)!=EOF){
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
getchar();
btree(n);
char op[2];
ll num1,num2;
for(int kk=0;kk
待续~~~~~~~