[ICPC 2019 Xuzhou R] Yuuki and a problem 题解
wzb13958817049 · · 题解
单点修改,区间查询集合
不带修就是神秘数,考虑这题是如何做的。
我们将
但是可能过不去,考虑神秘数的倍增分块写法,按照
-
- 否则答案就是
now+1 。
那么可以开
#include<bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
using namespace std;
constexpr ll N=2e5+5,inf=1e18;
ll n,m,a[N],id[N];
struct Tree{
ll w;
struct node{
ll sum,mn;
}tree[N<<2];
inline void pushup(node &A,node B,node C){
A.sum=B.sum+C.sum;
A.mn=min(B.mn,C.mn);
}
void build(int rt,int l,int r){
if(l==r){
if((1<<w)<=a[l] && a[l]<(1<<w+1)) tree[rt]={a[l],a[l]};
else tree[rt]={0,inf};
return ;
}
int mid=l+r>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
pushup(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void modify(int rt,int l,int r,int x,node t){
if(l==r){
tree[rt]=t;
return ;
}
int mid=l+r>>1;
if(x<=mid) modify(rt<<1,l,mid,x,t);
else modify(rt<<1|1,mid+1,r,x,t);
pushup(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
node query(int rt,int l,int r,int ql,int qr){
if(ql<=l && r<=qr) return tree[rt];
int mid=l+r>>1;
node res={0,inf};
if(ql<=mid) pushup(res,res,query(rt<<1,l,mid,ql,qr));
if(qr>mid) pushup(res,res,query(rt<<1|1,mid+1,r,ql,qr));
return res;
}
}tr[21];
inline ll getid(ll x){ll w=0;while((1<<w)<=x){if((1<<w+1)>x) return w;w++;}}
signed main(){
ios::sync_with_stdio(0),cout.tie(0),cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=0;i<=19;i++) tr[i].w=i,tr[i].build(1,1,n);
while(m--){
ll op,x,y;cin>>op>>x>>y;
if(op==1){
tr[getid(a[x])].modify(1,1,n,x,{0,inf});
tr[getid(y)].modify(1,1,n,x,{y,y});
a[x]=y;
}else{
ll now=0;
for(int w=0;w<=19;w++){
Tree::node t=tr[w].query(1,1,n,x,y);
if(t.mn<=now+1) now+=t.sum;
else break;
}
cout<<now+1<<"\n";
}
}
return 0;
}