本人深受动态开点的影响(动态开点好处多
决定将线段树写法全部变成动态开点,例如build函数
void build(int &u,int l,int r)
{
if(!u) u=++num;
tree[u].l=l;
tree[u].r=r;
if(l==r)
{
tree[u].val=v[l];
return ;
}
int mid=(l+r)>>1;
build(tree[u].lson,l,mid);
build(tree[u].rson,mid+1,r);
pushup(u);
}
至于其他的函数都是一样的qwq
省事了不少
接着总结一些没用的东西
众所周知,线段树可以改的地方就是pushup和pushdown
pushdown就是改标记,常见的线段树标记:
和,乘
异或和
前后缀
区间01翻转
区间染色
对于pushup的应用就是利用线段树算出当前的区间答案,然后将不可以快速合并的条件转化
转化成仅仅针对于左区间的答案和右区间递归的结果
关于可持久化有人说很难打,我觉得还好啊,build都不需要
下面粘贴一下modify
int modify(int last,int l,int r,int x)
{
int now=++cnt;
if(l==r)
{
//do something
return now;
}
int mid=(l+r)>>1;
if(x<=mid)
{
tree[now].lson=modify(tree[last].lson,l,mid,x);
tree[now].rson=tree[last].rson;
}
else
{
tree[now].rson=modify(tree[last].rson,mid+1,r,x);
tree[now].lson=tree[last].lson;
}
return now;
}
不麻烦吧qwq
普通线段树还有啥用法希望dalao指点