Solution-P8582
首先序列长度不是
然后我们要知道,01-trie 和线段树是等价的。对于点
我们先考虑从点
我们再考虑点
- 如果左右子树都可以走,则左右子树中的叶子均没有任何贡献,
val_j 为val_{lc}+val_{rc} 。 - 如果只有左子树可以走,因为右子树除了右儿子以外的其他部分和左子树是一样的,同时右子树的所有叶子都需要额外加上右儿子的贡献,
val_j 为2val_{lc}+2^{dep_j-1}\times2^{dep_j-1} 。只有右子树可以走的情况同理。 - 否则,
val_j 为-1 ,表示点j 的子树不可以走。
修改操作直接上线段树打懒标记,如果点
时间复杂度
01-trie 的题直接讲都非常抽象,建议配合代码理解。代码展示:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int v,n,m,k,dep[524288],val[524288],tag[524288];
inline void pushup(int p){
if(val[p<<1]!=-1&&val[p<<1|1]!=-1){
val[p]=val[p<<1]+val[p<<1|1];
}
else if(val[p<<1]!=-1){
val[p]=(val[p<<1]<<1)+((int)(1)<<(dep[p]<<1)-2);
}
else if(val[p<<1|1]!=-1){
val[p]=(val[p<<1|1]<<1)+((int)(1)<<(dep[p]<<1)-2);
}
else{
val[p]=-1;
}
}
inline void pushdown(int p){
if(tag[p]!=-1){
if(tag[p]){
val[p<<1]=val[p<<1|1]=0;
}
else{
val[p<<1]=val[p<<1|1]=-1;
}
tag[p<<1]=tag[p<<1|1]=tag[p];
tag[p]=-1;
}
}
inline void build(int l,int r,int p,int t){
tag[p]=-1;
dep[p]=t;
if(l==r){
if(l>n){
val[p]=-1;
}
return;
}
build(l,l+r>>1,p<<1,t-1);
build((l+r>>1)+1,r,p<<1|1,t-1);
pushup(p);
}
inline void update(int l,int r,int p,int a,int b,int c){
if(a<=l&&r<=b){
tag[p]=c;
if(c){
val[p]=0;
}
else{
val[p]=-1;
}
return;
}
pushdown(p);
if(a<=(l+r>>1)){
update(l,l+r>>1,p<<1,a,b,c);
}
if(b>(l+r>>1)){
update((l+r>>1)+1,r,p<<1|1,a,b,c);
}
pushup(p);
}
inline int find(int p,int t,int s){
if(dep[p]==t){
return val[p];
}
pushdown(p);
if(val[(p<<1)|(s>>dep[p]-1&1)]!=-1){
return find((p<<1)|(s>>dep[p]-1&1),t,s);
}
else{
return find((p<<1)|(s>>dep[p]-1&1^1),t,s)+((int)(1)<<dep[p]+t-1);
}
}
inline int query(int l,int r,int p,int a,int b,int s){
if(a<=l&&r<=b){
return find(1,dep[p],s);
}
int c=0;
pushdown(p);
if(a<=(l+r>>1)){
c+=query(l,l+r>>1,p<<1,a,b,s);
}
if(b>(l+r>>1)){
c+=query((l+r>>1)+1,r,p<<1|1,a,b,s+(1<<dep[p]-1));
}
return c;
}
signed main(){
int p,a,b;
cin.tie(nullptr)->sync_with_stdio(0);
cin>>v>>m>>n;
for(;(1<<k)<=n;k++);
build(0,(1<<k)-1,1,k);
while(v--){
cin>>a>>b;
update(0,(1<<k)-1,1,a,b,0);
}
while(m--){
cin>>p>>a>>b;
if(p==0){
if(val[1]==-1){
cout<<"Death\n";
}
else{
cout<<query(0,(1<<k)-1,1,a,b,0)<<'\n';
}
}
else{
update(0,(1<<k)-1,1,a,b,p-1);
}
}
return 0;
}