整体二分模板(带修)
2022/2/16 23:13:47
本文主要是介绍整体二分模板(带修),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
P2617
#include<cstdio> #include<vector> #include<iostream> #include<algorithm> using namespace std; const int MAXN=1e5+5; int n,m,Ans[MAXN<<2],cg[MAXN<<2],tot,va[MAXN<<2],b[MAXN<<2],c1; struct SG{ int l,r,sum; }t[MAXN<<2]; struct que{ int id,l,r,k,t,v; que(){}; que(int I,int L,int R,int K,int T,int V){id=I,l=L,r=R,k=K,t=T,v=V; } }; vector<que>q; bool cmp(que x,que y){return x.t<y.t; } void UPD(int p){t[p].sum=t[p<<1].sum+t[p<<1|1].sum; } void bui(int p,int l,int r){ t[p].l=l,t[p].r=r;t[p].sum=0; if(l==r) return; int mid=(l+r)>>1; bui(p<<1,l,mid);bui(p<<1|1,mid+1,r); } void upd(int p,int x,int k){ if(t[p].l==t[p].r){t[p].sum+=k;return;} int mid=(t[p].l+t[p].r)>>1; if(x<=mid) upd(p<<1,x,k); else upd(p<<1|1,x,k); UPD(p); } int ask(int p,int L,int R){ if(t[p].l>=L&&t[p].r<=R) return t[p].sum; int mid=(t[p].l+t[p].r)>>1,res=0; if(L<=mid) res+=ask(p<<1,L,R); if(R>mid) res+=ask(p<<1|1,L,R); return res; } void solve(int L,int R,vector<que>v){ // printf("L,R:%d %d\n",L,R); if(L==R){ for(unsigned int i=0;i<v.size();i++){ if(v[i].id) Ans[v[i].id]=cg[L]; } return; } int mid=(L+R)>>1; vector<que>v1,v2;vector<int>tmp; for(unsigned int i=0;i<v.size();i++){ if(v[i].id){ int tt=ask(1,v[i].l,v[i].r); if(v[i].k<=tt) v1.push_back(v[i]); else v[i].k-=tt,v2.push_back(v[i]); } else{ if(v[i].r<=mid) v1.push_back(v[i]),upd(1,v[i].l,v[i].v),tmp.push_back(i); else v2.push_back(v[i]); } } for(unsigned int i=0;i<tmp.size();i++) upd(1,v[tmp[i]].l,-v[tmp[i]].v); solve(L,mid,v1);solve(mid+1,R,v2); } int calc(int x){return lower_bound(b+1,b+1+c1,x)-b; } int main(){ scanf("%d%d",&n,&m); bui(1,1,n); for(int i=1;i<=n;i++){ int x;scanf("%d",&x);q.push_back((que){0,i,x,0,0,1});va[i]=x;b[i]=x; } int oo=0,pp=n; for(int i=1;i<=m;i++) { string c; cin>>c; if(c[0]=='C'){ int x,y;scanf("%d%d",&x,&y); q.push_back((que){0,x,va[x],0,++oo,-1}); va[x]=y;b[++pp]=y; q.push_back((que){0,x,y,0,++oo,1}); } else{ int l,r,k;scanf("%d%d%d",&l,&r,&k); q.push_back((que){++tot,l,r,k,++oo,0}); } } sort(b+1,b+1+pp); c1=unique(b+1,b+1+pp)-b-1; // printf("dd:%d\n",c1); // sort(q.begin(),q.end(),cmp); for(unsigned int i=0;i<q.size();i++){ if(!q[i].id){int tmp=q[i].r;q[i].r=calc(q[i].r);cg[q[i].r]=tmp;} } solve(1,c1,q); for(int i=1;i<=tot;i++) printf("%d\n",Ans[i]); return 0; }
这篇关于整体二分模板(带修)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南