CF679E Bear and Bad Powers of 42
XVIII.CF679E Bear and Bad Powers of 42
一个显然的想法是,观察到可能的值域()内不会有很多(准确地说,一共个)的整数次幂。于是我们考虑每次暴力修改,则每个数最多被处理次,复杂度显然是可以承受的。
于是我们现在问题就转变为判断一个区间中是否存在的整数次幂。
我们对于每个数,维护这个数到下一个的次幂的距离,并在区间上维护这一距离的。在区间加的时候,代表区间加的tag增加,同时代表区间的tag减少。
假如区间的tag在减少后为了,就直接返回找到了;否则,如果其大于,返回没找到;否则,即其小于,无法判断有没有找到,需要继续往子区间内遍历。
假如遍历到一个位置,发现这个位置的区间修改的tag不为(这可能意味着这段区间刚刚被进行了一次区间修改,或是访问到了叶节点——叶节点的区间修改tag(即它自己的值)显然是不为的),那就可以直接由这个tag推出区间中的(毕竟整个区间的值都是相等的),再返回这个是否为即可。
这也意味着我们的pushdown
函数要比较细心:假设当前区间修改tag不为,显然下传时,应该把儿子的tag全都覆盖掉——区间修改tag赋成下传的tag,区间加的tag赋成;同时,区间的值也要下传,这就避免了在儿子处再算一遍的局面。
假设当前区间加tag不为(显然,此时区间修改tag肯定为),下传时注意判断儿子的区间修改tag是否为,为则加到区间加tag上,否则直接加到区间修改tag上;同时,在修改后,记得同时修改区间。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
const int lim=11;
ll pov[20]={1,42,1764,74088,3111696,130691232,5489031744ll,230539333248ll,9682651996416ll,406671383849472ll,17080198121677824ll};
#define lson x<<1
#define rson x<<1|1
#define mid ((l+r)>>1)
struct SegTree{
ll tagmodi,tagadd,mn;
}seg[400100];
void ADD(int x,ll y){if(seg[x].tagmodi)seg[x].tagmodi+=y;else seg[x].tagadd+=y;seg[x].mn-=y;}
void REFRESH(int x){seg[x].mn=*lower_bound(pov,pov+lim,seg[x].tagmodi)-seg[x].tagmodi;}
void MODI(int x,ll y){seg[x].tagmodi=y,seg[x].tagadd=0,REFRESH(x);}
void pushdown(int x){
if(seg[x].tagmodi){
seg[lson].tagmodi=seg[rson].tagmodi=seg[x].tagmodi;
seg[lson].mn=seg[rson].mn=seg[x].mn;
seg[lson].tagadd=seg[rson].tagadd=0;
seg[x].tagmodi=0;
}
if(seg[x].tagadd)ADD(lson,seg[x].tagadd),ADD(rson,seg[x].tagadd),seg[x].tagadd=0;
}
void pushup(int x){seg[x].mn=min(seg[lson].mn,seg[rson].mn);}
void build(int x,int l,int r){
if(l==r){scanf("%lld",&seg[x].tagmodi),REFRESH(x);return;}
build(lson,l,mid),build(rson,mid+1,r),pushup(x);
}
void setval(int x,int l,int r,int L,int R,int val){
if(l>R||r<L)return;
if(L<=l&&r<=R){MODI(x,val);return;}
pushdown(x),setval(lson,l,mid,L,R,val),setval(rson,mid+1,r,L,R,val),pushup(x);
}
bool find(int x,int l,int r){
if(seg[x].mn>=0)return seg[x].mn==0;
if(seg[x].tagmodi){REFRESH(x);return seg[x].mn==0;}
pushdown(x);
bool ret=find(lson,l,mid)|find(rson,mid+1,r);
pushup(x);
return ret;
}
bool add(int x,int l,int r,int L,int R,int val){
if(l>R||r<L)return false;
if(L<=l&&r<=R){
ADD(x,val);
return find(x,l,r);
}
pushdown(x);
bool ret=add(lson,l,mid,L,R,val)|add(rson,mid+1,r,L,R,val);
pushup(x);
return ret;
}
ll query(int x,int l,int r,int P){
if(l==r)return seg[x].tagmodi;
pushdown(x);
ll ret=(P<=mid?query(lson,l,mid,P):query(rson,mid+1,r,P));
pushup(x);
return ret;
}
//void iterate(int x,int l,int r){if(l==r)printf("(%lld:%lld)",seg[x].tagmodi,seg[x].mn);else pushdown(x),iterate(lson,l,mid),iterate(rson,mid+1,r),pushup(x);}
int main(){
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i=1,a,b,c,d;i<=m;i++){
scanf("%d%d",&a,&b);
if(a==1)printf("%lld\n",query(1,1,n,b));
else{
scanf("%d%d",&c,&d);
if(a==2)setval(1,1,n,b,c,d);
else while(add(1,1,n,b,c,d));
}
// iterate(1,1,n),puts("");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?