ACM 线段树 专题
程序员文章站
2022-07-13 11:31:31
...
其中应该有我以前 刷过的题吧 没有办法 算法这东西 一不刷 就会忘。。。。 像这道题 我 就wa了 四发 才过
但是 我 以前确实过过。。。
再重新理解一下吧 大概就是 线段树 就是 左右 节点 然后 上面就是 我们的 和 建立的时候和每次修改 都要更新一下父节点 也就是子节点的和
树这个东西 仔细想想 确实集合了 链表和数组的优点
链表 的优点就是可以 增删改 而 数组就是 查询 还有排序比较 简便 但是当你需要 大量的 查询 增删改的时候
确实需要树这个东西 什么 红黑 01 线段 字典 就开始 往上甩了
线段树 的概念 百度 或者 很多大佬应该比我讲的清楚 我直接 粘代码了 哦 对了 第一个说我 是渣男的人 诞生了。。
某平 说的 写到我的小本本上面
敌兵布阵 HDU - 1166
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
int s[50500<<2];
char str[25];
int l,ll;
void upset(int index)
{
s[index]=s[index<<1]+s[index<<1|1];
}
int sun=0;
void build(int l,int r,int index)
{
if(l==r)
{
scanf("%d",&s[index]);
return;
}
int mid=(l+r)>>1;
build(l,mid,index<<1);
build(mid+1,r,index<<1|1);
upset(index);
}
int Query(int l,int r,int ll,int rr,int index)
{
if(ll>=l&&rr<=r)
{
return s[index];
}
int mid=(rr+ll)/2;
int ans=0;
if(l<=mid)
{
ans+=Query(l,r,ll,mid,index<<1);
}
if(r>mid)
{
ans+=Query(l,r,mid+1,rr,index<<1|1);
}
return ans;
}
void update(int l,int c,int ll,int rr,int index)
{
if(ll==rr)
{
s[index]+=c;
return;
}
int mid=(ll+rr)/2;
if(l>mid)
{
update(l,c,mid+1,rr,index<<1|1);
}
else
{
update(l,c,ll,mid,index<<1);
}
upset(index);
}
void go(int n)
{
while(~scanf("%s",str))
{
if(str[0]=='E')
{
break;
}
scanf("%d%d",&l,&ll);
if(str[0]=='A')
{
update(l,ll,1,n,1);
}
else if(str[0]=='S')
{
update(l,-ll,1,n,1);
}
else if(str[0]=='Q')
{
printf("%d\n",Query(l,ll,1,n,1));
}
}
}
int main()
{
int T,n;
int kkk=0;
scanf("%d",&T);
while(T--)
{
kkk++;
memset(s,0,sizeof(s));
printf("Case %d:\n",kkk);
scanf("%d",&n);
build(1,n,1);
go(n);
//printf("go!\n");
}
return 0;
}
B - I Hate It HDU - 1754
这个题 和上面的一样 只不过加 变成了 找出最大值而已
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
int s[200000<<4];
void upset(int index)
{
s[index]=max(s[index<<1],s[index<<1|1]);
}
void build(int l,int r,int index)
{
if(l==r)
{
scanf("%d",&s[index]);
return;
}
int mid=(l+r)/2;
build(l,mid,index<<1);
build(mid+1,r,index<<1|1);
upset(index);
}
int Query(int l,int r,int ll,int rr,int index)
{
if(ll>=l&&rr<=r)
{
//printf("%d\n",s[index]);
return s[index];
}
int mid=(ll+rr)/2;
int ans=0;
if(r>mid)
{
ans=max(Query(l,r,mid+1,rr,index<<1|1),ans);
}
if(l<=mid)
{
ans=max(Query(l,r,ll,mid,index<<1),ans);
}
return ans;
}
void update(int l,int c,int ll,int rr,int index)
{
if(ll==rr)
{
s[index]=c;
return;
}
int mid=(ll+rr)/2;
if(l>mid)
{
update(l,c,mid+1,rr,index<<1|1);
}
else
{
update(l,c,ll,mid,index<<1);
}
upset(index);
}
int main()
{
int n,m,l,r;
char chioce[2];
while(~scanf("%d%d",&n,&m))
{
build(1,n,1);
while(m--)
{
scanf("%s%d%d",chioce,&l,&r);
if(chioce[0]=='Q')
{
printf("%d\n",Query(l,r,1,n,1));
}
else
{
update(l,r,1,n,1);
}
}
}
return 0;
}