2024.10.17 模拟赛T3 题解
题意
给定一个长度为
-
1 L R x
,对于 ,若 则让 ,否则让 。 -
2 L R x
,对于 ,让 。 -
3 h
,让 。 -
4 L R
,查询有多少 满足 。 -
5 L R
,查询有多少 满足 。
解法
开一个线段树,维护区间内有多少
显然可以暴力处理操作一后
对于 set
在操作一前找到
这样就写完了。
#include<bits/stdc++.h>
#define pb emplace_back
#define pob pop_back
#define mp make_pair
using namespace std;
typedef long long ll;
typedef __int128 LL;
const ll maxn=200007,ee=1e18,p=998244353;
ll n,q,a[maxn],vis[maxn];
set<pair<ll,ll> > st;
vector<ll> del;
struct Node{
ll mn,cnt;
Node operator+(Node o){
Node res;
if(mn==-1) res.mn=o.mn,res.cnt=o.cnt;
else if(o.mn==-1) res.mn=mn,res.cnt=cnt;
else if(mn==o.mn) res.mn=mn,res.cnt=cnt+o.cnt;
else if(mn<o.mn) res.mn=mn,res.cnt=cnt;
else res.mn=o.mn,res.cnt=o.cnt;
return res;
}
};
struct Tree{
Node t[maxn<<2];
ll val[maxn<<2],add[maxn<<2];
void pushup(ll rt){
val[rt]=val[rt<<1]+val[rt<<1|1];
t[rt]=t[rt<<1]+t[rt<<1|1];
}
void pushdown(ll rt){
if(!add[rt]) return;
if(t[rt<<1].mn!=-1) t[rt<<1].mn+=add[rt];
if(t[rt<<1|1].mn!=-1) t[rt<<1|1].mn+=add[rt];
add[rt<<1]+=add[rt],add[rt<<1|1]+=add[rt],add[rt]=0;
}
void upd1(ll l,ll r,ll x,ll y,ll z,ll rt){
if(x<=l&&r<=y){
//cout<<l<<" "<<r<<" "<<t[rt].mn<<"\n";
if(t[rt].mn==-1) return;
if(l==r&&t[rt].mn<z) return val[rt]=1,t[rt]=Node{-1,0},void();
if(t[rt].mn>=z) return t[rt].mn-=z,add[rt]-=z,void();
if(l!=r) pushdown(rt); ll mid=(l+r)>>1;
upd1(l,mid,x,y,z,rt<<1),upd1(mid+1,r,x,y,z,rt<<1|1);
pushup(rt); return;
}
pushdown(rt); ll mid=(l+r)>>1;
if(x<=mid) upd1(l,mid,x,y,z,rt<<1); if(mid<y) upd1(mid+1,r,x,y,z,rt<<1|1);
pushup(rt);
}
void upd2(ll l,ll r,ll x,ll y,ll z,ll rt){
if(x<=l&&r<=y) return add[rt]+=z,t[rt].mn+=z,void(); pushdown(rt); ll mid=(l+r)>>1;
if(x<=mid) upd2(l,mid,x,y,z,rt<<1); if(mid<y) upd2(mid+1,r,x,y,z,rt<<1|1);
pushup(rt);
}
void build(ll l,ll r,ll rt){
if(l==r) return cin>>t[rt].mn,t[rt].cnt=1,void(); ll mid=(l+r)>>1;
build(l,mid,rt<<1),build(mid+1,r,rt<<1|1),pushup(rt);
}
ll qry1(ll l,ll r,ll x,ll y,ll rt){
if(x<=l&&r<=y) return val[rt]; pushdown(rt); ll mid=(l+r)>>1,res=0;
if(x<=mid) res+=qry1(l,mid,x,y,rt<<1); if(mid<y) res+=qry1(mid+1,r,x,y,rt<<1|1);
return res;
}
Node qry2(ll l,ll r,ll x,ll y,ll rt){
if(l>r||r<x||y<l) return Node{-1,0};
if(x<=l&&r<=y) return t[rt]; pushdown(rt); ll mid=(l+r)>>1;
return qry2(l,mid,x,y,rt<<1)+qry2(mid+1,r,x,y,rt<<1|1);
}
}tree;
int main(void){
freopen("simulator.in","r",stdin);
freopen("simulator.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n; tree.build(1,n,1);
cin>>q;
for(ll i=1,opt,x,y,z,tmp;i<=q;i++){
cin>>opt>>x;
if(opt==1){
cin>>y>>z;
auto it=st.lower_bound(mp(x,0));
del.clear();
for(;it!=st.end()&&it->first<=y;it++){
tmp=it->first;
tree.upd2(1,n,tmp,tmp,z,1);
del.pb(tmp);
}
for(auto t:del){
auto pir=*st.lower_bound(mp(t,0));
st.erase(pir),vis[t]--;
if(pir.second>1) pir.second--,st.insert(pir);
}
tree.upd1(1,n,x,y,z,1);
}else if(opt==2){
cin>>y>>z;
tree.upd2(1,n,x,y,z,1);
}else if(opt==3){
if(vis[x]){
auto pir=*st.find(mp(x,vis[x]));
st.erase(pir); pir.second++;
st.insert(pir);
}else st.insert(mp(x,1));
vis[x]++;
}else if(opt==4){
cin>>y;
cout<<tree.qry1(1,n,x,y,1)<<"\n";
}else{
cin>>y;
Node res=tree.qry2(1,n,x,y,1);
if(res.mn==0) cout<<res.cnt<<"\n";
else cout<<"0\n";
}
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· DeepSeek本地性能调优
· 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略