线段树 处理区间问题的高级数据结构
听说树状数组能做(树状数组我不会啊QAQ )的线段树都能做,就丢个线段树吧QAQ
快NOIP了还是好弱怎么办 急在线等
NOIP Loiers RP ++!!
void up(int p)//更新数据
{
tree[p].sum = tree[p<<1].sum + tree[p<<1|1].sum;
tree[p].max = max(tree[p<<1].max,tree[p<<1|1].max);
tree[p].min = min(tree[p<<1].min,tree[p<<1|1].min);
}
void push(int p)//标记下放
{
tree[p<<1].sum += tree[p].add * (tree[p<<1].r - tree[p<<1].l + 1);
tree[p<<1].add += tree[p].add;
tree[p<<1|1].sum += tree[p].add * (tree[p<<1|1].r - tree[p<<1|1].l + 1);
tree[p<<1|1].add += tree[p].add;
tree[p].add = 0;
}
void build(int p,int l,int r)//建树
{
tree[p].l = l;
tree[p].r = r;
if(l == r)
{
tree[p].min = tree[p].max = tree[p].sum = num[l];
return ;
}
int mid = (l + r) >> 1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
up(p);
}
void change_qujian(int p,int l,int r,int v)//区间修改
{
if(l <= tree[p].l && tree[p].r <= r)
{
tree[p].sum += v * (tree[p].r - tree[p].l +1);
tree[p].max += v;
tree[p].min += v;
tree[p].add += v;
return;
}
push(p);
int mid = (tree[p].l + tree[p].r) >> 1;
if(l <= mid ) change(p<<1,l,r,v);
if(mid < r) change(p<<1|1,l,r,v);
up(p);
}
void change_dian(int p,int a,int x)//单点修改
{
if(a==tree[p].l&&tree[p].r==a)
{
tree[p].sum+=x;
tree[p].add+=x;
return;
}
push(p);
int mid = (tree[p].l+tree[p].r)/2;
if(a <= mid) change(p*2,a,x);
if(mid < a) change(p*2+1,a,x);
up(p);
}
ll ask(int p,int l)//单点查询
{
if(l == tree[p].l && tree[p].r == l)
{
return tree[p].sum;
}
push(p);
int mid = (tree[p].l + tree[p].r)/2;
ll ans = 0;
if(l <= mid) ans += ask(p*2,l);
if(mid < l) ans += ask(p*2+1,l);
return ans;
}
ll ask_min(int p,int l,int r)//区间最小值
{
if(l <= tree[p].l && tree[p].r <= r)
{
return tree[p].min;
}
push(p);
int mid = (tree[p].l + tree[p].r) >> 1;
ll ans = 21474836472333333;
if(l <= mid) ans = min(ans,ask_min(p<<1,l,r));
if(mid < r) ans = min(ans,ask_min(p<<1|1,l,r));
return ans;
}
ll ask_max(int p,int l,int r)//区间最大值
{
if(l <= tree[p].l && tree[p].r <= r)
{
return tree[p].max;
}
push(p);
int mid = (tree[p].l + tree[p].r) >> 1;
ll ans = 0;
if(l <= mid) ans = max(ans,ask_max(p<<1,l,r));
if(mid < r) ans = max(ans,ask_max(p<<1|1,l,r));
return ans;
}
ll ask_sum(int p,int l,int r)//区间求和
{
if(l <= tree[p].l && tree[p].r <= r)
{
return tree[p].sum;
}
push(p);
int mid = (tree[p].l + tree[p].r) >> 1;
ll ans = 0;
if(l <= mid) ans += ask_sum(p<<1,l,r);
if(mid < r) ans += ask_sum(p<<1|1,l,r));
return ans;
}