#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn=1e5+7;
int a[maxn],tree[maxn*4];
int lz[maxn*4];
void build(int node ,int start, int endd)
{
if(start == endd)//叶子节点
{
tree[node] = a[start];
return ;
}
else{
int mid = start + ((endd - start) >> 1);
int lson = node << 1 ;//左儿子:2 * node
int rson = (node << 1) | 1;//右儿子:2 * node + 1
build(lson, start, mid);
build(rson, mid+1, endd);
tree[node] = tree[lson] + tree[rson];
}
}
//单点更新,idx为需要更新的叶子节点编号,add为更改值
void update(int node, int start, int endd, int idx, int instead)
{
if(start == endd)
{
tree[start] = instead;
return ;
}
else
{
int mid = start + (endd - start) >> 1;
int lson = (node << 1);
int rson = (node << 1) | 1;
if( idx <= mid)
{
update(lson, start, mid, idx, instead);
}
else
{
update(rson, mid+1, endd, idx, instead);
}
tree[node] = tree[lson] + tree[rson];
}
}
//单点查询
LL query(LL node,LL l,LL r,LL x)
{
if(l==r&&l==x) return tree[num];
LL mid=(l+r)>>1,tmp;
if(x<=mid) tmp=query(num*2,l,mid,x);
else tmp=query(num*2+1,mid+1,r,x);
return tmp+tree[num];
}
LL query(int node, int start, int endd, int l, int r)
{
LL sum=0;
if(l>endd || r<start)
{
return 0;
}
if(l<=start && r>=endd)
{
return tree[node];
}
int mid = start + (endd - start) >> 1;
int lson = node << 1;
int rson = (node << 1) | 1;
LL sum_left = query(lson, start, mid, l, r);
LL sum_right = query(rson, mid+1, endd, l, r);
sum = sum_left + sum_right;
return sum;
}
------------------------------------------------------------------------------
//区间加值
void push_up(int node)
{
tree[node] = tree[node<<1] + tree[(node<<1)|1];
}
void push_down(int node, int l, int r)
{
int lson = (node << 1);
int rson = (node << 1) | 1;
if(lz[node])
{
lz[lson] = lz[node];
lz[rson] = lz[node];
int mid = l + (r - l) >> 1;
tree[lson] += lz[node] * (mid-l+1);
tree[rson] += lz[node] * (r-mid);
lz[node] = 0; //lazy标记使用完后需清零
}
}
void update(int node, int start, int endd, int l, int r, int add)
{
if(l<=start && r>=endd)//当前结点被所查询的区间覆盖
{
lz[node] += add; //更新该结点所需的更新信息
tree[node] += add * (r-l+1);//更新该结点信息
return ; //lazy只需记录到当前结点
}
push_down(node, start, endd);
int mid = start + ((endd - start)>>1);int mid = l + ((r-l)>>1);
if(l <= mid) update( node<<1, start, mid, l, r, add);
if(r >= mid) update( (node<<1)|1, mid+1, endd, l, r, add);
push_up(node);//向上递归时需一步一步更新回父节点
}
LL query(int node, int start, int endd, int l, int r)
{
if(l <= start && r>=endd)
{
return tree[node];
}
push_down(node, start, endd);
int mid = start + ((endd - start)>>1);
LL ans = 0;
if(l <= mid) ans += query( node<<1, start, mid, l, r);
if(r >= mid+1) ans += query( node<<1|1, mid+1, endd, l, r);
return ans;
}
------------------------------------------------------------------------------
//区间改值
void pushup(int node)
{
tree[node] = tree[node<<1] + tree[node<<1|1];
}
void pushdown(int node, int start, int endd)
{
if(lz[node])
{
int c = lz[node];
lz[node<<1] = c;
lz[node<<1|1] = c;
int mid = start + ((endd - start)>>1);
tree[node<<1] = (mid-start+1) * c;
tree[node<<1] = (endd-mid) * c;
lz[node] = 0;
}
}
void update(int node, int start, int endd, int l, int r,int c)
{
if(l <= start && r >= endd)
{
lz[node] = c;
tree[node] = (endd-start+1) * c;
return ;
}
pushdown(node, start, endd);
int mid = start + ((endd - start)>>1);
if(l <= mid) update(node<<1, start, mid, l, r, c);
if(r >= mid+1) update(node<<1|1, mid+1, endd, l, r,c);
pushup(node);
}
LL query(int node, int start, int endd, int l, int r)
{
if(l <= start && r >= endd)
{
return tree[node];
}
pushdown(node, start, endd);
int mid = start + ((endd-start)>>1);
LL ans=0;
if(l <= mid) ans+=query(node<<1, start, mid, l, r);
if(r >= mid+1) ans+=query(node<<1|1, mid+1, endd, l, r);
return ans;
}
int main()
{
int q=1;
for(int i=1;i<=6;i++)
{
a[i]=q++;
}
build(1,1,6);
for(int i=1;i<=15;i++)
{
printf("tree[%d]:%d\n",i,tree[i]);
}
return 0;
}
--------------------------------------------------------------------------------------
//求区间最大值
void update(int o,int l,int r,int ind,int ans){ //o、l、r为当前更新到的结点、左右端点,ind为需要修改的叶子结点左端点,ans为需要修改成的值;
if(l==r){ //若当前更新点的左右端点相等即到叶子结点时,直接更新信息并返回
st[o]=ans;
return;
}
int m=l+((r-l)>>1);
if(ind<=m){ //若需要更新的叶子结点在当前结点的左儿子结点的范围内,则递归更新左儿子结点,否则更新右儿子结点
update(o<<1,l,m,ind,ans);
}
else{
update((o<<1)|1,m+1,r,ind,ans);
}
st[o]=max(st[o<<1],st[(o<<1)|1]);//递归回之后用儿子结点更新父节点(此处是区间最大值)
}
{ //在main函数中的语句
update(1,1,n,ind,ans);
}
int query(int o,int l,int r,int ql,int qr){ //ql、qr为需要查询的区间左右端点
if(ql>r||qr<l) return -1; //若当前结点和需要查找的区间不相交,则返回一个对于区间查询无关的值(如求和时返回0,求最大值时返回-1等)
if(ql<=l&&qr>=r) return st[o]; //若当前结点的区间被需要查询的区间覆盖,则返回当前结点的信息
int m=l+((r-l)>>1);
int p1=query(o<<1,l,m,ql,qr),p2=query((o<<1)|1,m+1,r,ql,qr); //p1为查询左儿子结点得到的信息,p2为查询右儿子结点得到的信息
return max(p1,p2); //综合两个儿子结点的信息并返回
}
{ //main函数中的语句
printf("%d\n",query(1,1,n,a,b));
}