[ABC256Ex] I like Query Problem
题意#
区间整除,区间推平,查询区间和。
大家好啊,我喜欢暴力乱搞,所以这题我用暴力乱搞 AC 了。
首先观察到操作
但是有个问题是,如果加上区间推平操作之后,我们每次推平之后就不能维持原来的最大值了,这样最坏复杂度就又会退化成纯暴力的复杂度。
但是区间推平这个操作我们还可以用另一个东西去维护啊,没错就是
但是如果区间推平操作很少的话,
所以我们直接合在一起乱搞啊!
将全部操作存下来,同时给区间推平操作计数,如果次数大于
然后你就会发现这东西跑得飞快(。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define il inline
#define re register
const int N=500500;
int n,m,a[N],cnt;
struct query{
int op,l,r,x;
}q[N];
il int read(){
re int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*f;
}
struct Chtholly{
int l,r;
mutable int val;
Chtholly(int l,int r=0,int val=0):l(l),r(r),val(val){}
bool operator<(const Chtholly &a)const{
return l<a.l;
}
};
set<Chtholly>s;
#define It set<Chtholly>::iterator
il It Split(int pos){
It fnd=s.lower_bound(Chtholly(pos));
if(fnd!=s.end()&&fnd->l==pos)return fnd;
fnd--;
if(fnd->r<pos)return s.end();
int l=fnd->l,r=fnd->r,val=fnd->val;
s.erase(fnd);
s.insert(Chtholly(l,pos-1,val));
return s.insert(Chtholly(pos,r,val)).first;
}
il void Assign(int l,int r,int x){
It R=Split(r+1),L=Split(l);
s.erase(L,R);
s.insert(Chtholly(l,r,x));
}
il void update(int l,int r,int x){
It R=Split(r+1),L=Split(l);
for(re It i=L;i!=R;i++)i->val/=x;
}
il void solve(int l,int r){
int res=0;
It R=Split(r+1),L=Split(l);
for(re It i=L;i!=R;i++)
res+=(i->r-i->l+1)*i->val;
printf("%lld\n",res);
}
struct SegmentTree{
int sum,mx,tag;
}L[N<<2];
#define ls (id<<1)
#define rs (id<<1|1)
il void pushup(SegmentTree &fa,SegmentTree lson,SegmentTree rson){
fa.sum=lson.sum+rson.sum;
fa.mx=max(lson.mx,rson.mx);
}
il void pushdown(SegmentTree &fa,SegmentTree &lson,SegmentTree &rson,int l,int r){
if(!fa.tag)return;
int mid=(l+r)>>1,t=fa.tag;
lson={(mid-l+1)*t,t,t};
rson={(r-mid)*t,t,t};
fa.tag=0;
}
il void upd(int id,int l,int r,int x,int y,int z){
if(!L[id].mx)return;
if(l==r){
L[id].sum/=z,L[id].mx/=z;
return;
}
int mid=(l+r)>>1;
pushdown(L[id],L[ls],L[rs],l,r);
if(x<=mid)upd(ls,l,mid,x,y,z);
if(y>mid)upd(rs,mid+1,r,x,y,z);
pushup(L[id],L[ls],L[rs]);
}
il void Ass(int id,int l,int r,int x,int y,int z){
if(l>=x&&r<=y){
L[id]={(r-l+1)*z,z,z};
return;
}
int mid=(l+r)>>1;
pushdown(L[id],L[ls],L[rs],l,r);
if(x<=mid)Ass(ls,l,mid,x,y,z);
if(y>mid)Ass(rs,mid+1,r,x,y,z);
pushup(L[id],L[ls],L[rs]);
}
il int GetSum(int id,int l,int r,int x,int y){
if(l>=x&&r<=y)return L[id].sum;
int mid=(l+r)>>1,res=0;
pushdown(L[id],L[ls],L[rs],l,r);
if(x<=mid)res+=GetSum(ls,l,mid,x,y);
if(y>mid)res+=GetSum(rs,mid+1,r,x,y);
pushup(L[id],L[ls],L[rs]);
return res;
}
il void build(int id,int l,int r){
if(l==r){
L[id]={a[l],a[l],0};
return;
}
int mid=(l+r)>>1;
build(ls,l,mid),build(rs,mid+1,r);
pushup(L[id],L[ls],L[rs]);
}
il void solve_odt(){
for(re int i=1;i<=n;i++)
s.insert(Chtholly(i,i,a[i]));
for(re int i=1;i<=m;i++){
if(q[i].op==1)update(q[i].l,q[i].r,q[i].x);
if(q[i].op==2)Assign(q[i].l,q[i].r,q[i].x);
if(q[i].op==3)solve(q[i].l,q[i].r);
}
}
il void solveSegmentTree(){
build(1,1,n);
for(re int i=1;i<=m;i++){
int op=q[i].op,l=q[i].l,r=q[i].r,x=q[i].x;
if(op==1)upd(1,1,n,l,r,x);
if(op==2)Ass(1,1,n,l,r,x);
if(op==3)printf("%lld\n",GetSum(1,1,n,l,r));
}
}
signed main(){
n=read(),m=read();
for(re int i=1;i<=n;i++)a[i]=read();
for(re int i=1;i<=m;i++){
q[i].op=read(),q[i].l=read(),q[i].r=read();
if(q[i].op!=3)q[i].x=read();
if(q[i].op==2)cnt++;
}
if(cnt>2000)solve_odt();
else solveSegmentTree();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!