求调线段树套fhq(

P3380 【模板】树套树

~~不会 FHQ 啊/fad~~ 如果平衡树维护的是有序序列可以试着用 BST 的性质来找每个区间的前驱/后缀然后再合并? 对 FHQ 不熟悉咱就不在您代码上修改了。 ```cpp int getPre(int &root,int v)//查找最大的比 v 小的数 { int u=root,res=-INF; while(u) { if(tree[u].v<v) res=max(res,tree[u].v),u=tree[u].s[1]; else u=tree[u].s[0]; } return res; } int getSuc(int &root,int v)//查找最小的比 v 大的数 { int u=root,res=INF; while(u) { if(tree[u].v>v) res=min(res,tree[u].v),u=tree[u].s[0]; else u=tree[u].s[1]; } return res; } int queryPre(int node,int l,int r,int x)//查找前驱 { if(l<=tr1[node].l&&tr1[node].r<=r) return getPre(tr1[node].root,x); int mid=tr1[node].l+tr1[node].r>>1; int res=-INF; if(l<=mid) res=max(res,queryPre(lnode,l,r,x)); if(r>mid) res=max(res,queryPre(rnode,l,r,x)); return res; } int querySuc(int node,int l,int r,int x)//查找后继 { if(l<=tr1[node].l && tr1[node].r<=r) return getSuc(tr1[node].root,x); int mid=tr1[node].l+tr1[node].r>>1; int res=INF; if(l<=mid) res=min(res,querySuc(lnode,l,r,x)); if(r>mid) res=min(res,querySuc(rnode,l,r,x)); return res; } ```
by RemiliaScar1et @ 2021-04-20 16:22:10


@[RemiliaScarlet◎](/user/278259) 那不如帮我调一下新写的带修莫队() ```cpp #include<bits/stdc++.h> using namespace std; #define int long long const int N=1e5+10,inf=2147483647; struct node { int l,r; int p; int num; int k; int id; }q[N]; struct ch { int from,to; int p; } c[N]; int n,m,t; int maxn; int maxm; int maxq,maxc; int a[N],typ[N*2]; int bl[N],sq; bool cmp(node x,node y) { if(bl[x.l]!=bl[y.l]) return x.l<y.l; if(x.r!=y.r) return x.r<y.r; return x.k>y.k; } int sn,b[N],bn[N],lbn[N],rbn[N],sum[N]; void change(int from,int to) { b[from]--; b[to]++; sum[bn[from]]--; sum[bn[to]]++; } int get_rank(int x) { int i=1; int ans=0; while(rbn[i]<x) { ans+=sum[i]; i++; } int k=lbn[i]; while(k<x) ans+=b[k],k++; return ans+1; } int get_key(int x) { int i=1; int ans=0; while(x>sum[i]) { x-=sum[i]; i++; } int k=lbn[i]; while(x>b[k]) { x-=b[k]; k++; } while(b[k]==0) k++; return typ[k]; } int ans[N]; signed main() { cin>>n>>m; sq=pow(n,0.6666); for(int i=1;i<=n;i++) { bl[i]=(i-1)/sq+1; cin>>a[i]; typ[++maxn]=a[i]; } for(int i=1;i<=m;i++) { int op; cin>>op; if(op==1) { int x,l,r; cin>>l>>r>>x; int p=++maxq; q[p].l=l; q[p].r=r; q[p].p=x; q[p].k=maxc; q[p].num=1; q[p].id=p; typ[++maxn]=x; } if(op==2) { int x,l,r; cin>>l>>r>>x; int p=++maxq; q[p].l=l; q[p].r=r; q[p].p=x; q[p].k=maxc; q[p].id=p; q[p].num=2; } if(op==3) { int p,v; cin>>p>>v; c[++maxc].from=a[p]; c[maxc].to=v; c[maxc].p=p; typ[++maxn]=v; a[p]=v; } if(op==4) { int x,l,r; cin>>l>>r>>x; int p=++maxq; q[p].l=l; q[p].r=r; q[p].p=x; q[p].num=4; q[p].k=maxc; q[p].id=p; typ[++maxn]=x; } if(op==5) { int x,l,r; cin>>l>>r>>x; int p=++maxq; q[p].l=l; q[p].r=r; q[p].p=x; q[p].num=5; q[p].k=maxc; q[p].id=p; typ[++maxn]=x; } } //for(int i=1;i<=maxq;i++) //cout<<"l:"<<q[i].l<<" r:"<<q[i].r<<" id:"<<q[i].id<<" p:"<<q[i].p<<" k:"<<q[i].k<<" op:"<<q[i].num<<endl; //for(int i=1;i<=maxc;i++) //cout<<c[i].from<<" "<<c[i].to<<endl; sort(q+1,q+maxq+1,cmp); sort(typ+1,typ+maxn+1); maxm=unique(typ+1,typ+maxn+1)-typ-1; //for(int i=1;i<=maxm;i++) cout<<typ[i]<<" "; //cout<<endl; sn=sqrt(maxm); t=maxm/sn; for(int i=1;i<=maxm;i++) bn[i]=(i-1)/sn+1; for(int i=1;i<=t;i++) { lbn[i]=(i-1)*sn+1; rbn[i]=i*sn; } if(t*sq<n) { t++; lbn[t]=(t-1)*sn+1; rbn[t]=n; } for(int i=1;i<=n;i++) a[i]=lower_bound(typ+1,typ+maxm+1,a[i])-typ; for(int i=1;i<=maxq;i++) if(q[i].num!=2) { q[i].p=lower_bound(typ+1,typ+maxm+1,q[i].p)-typ; } for(int i=1;i<=maxc;i++) { c[i].from=lower_bound(typ+1,typ+maxm+1,c[i].from)-typ; c[i].to=lower_bound(typ+1,typ+maxm+1,c[i].to)-typ; //cout<<typ[c[i].from]<<" "<<typ[c[i].to]<<endl; } int l=1,r=0,k=maxc; for(int i=1;i<=maxq;i++) { int ql=q[i].l,qr=q[i].r,qk=q[i].k,op=q[i].num,p=q[i].p; while(k<qk) { ++k; if(c[k].p>=l&&c[k].p<=r) change(c[k].from,c[k].to); a[c[k].p]=c[k].to; } while(k>qk) { if(c[k].p>=l&&c[k].p<=r) change(c[k].to,c[k].from); a[c[k].p]=c[k].from; --k; } while(r<qr) { ++r; b[a[r]]++; sum[bn[a[r]]]++; } while(l>ql) { --l; b[a[l]]++; sum[bn[a[l]]]++; } while(r>qr) { b[a[r]]--; sum[bn[a[r]]]--; --r; } while(l<ql) { b[a[l]]--; sum[bn[a[l]]]--; ++l; } //cout<<q[i].id<<" "<<l<<" "<<r<<endl; //cout<<l<<" "<<r<<" "<<k<<endl; //for(int i=1;i<=t;i++) cout<<typ[lbn[i]]<<" "<<typ[rbn[i]]<<" "<<sum[i]<<endl; //cout<<endl; if(op==1) ans[q[i].id]=get_rank(p); if(op==2) ans[q[i].id]=get_key(p); if(op==4) { int rank=get_rank(p); int val=get_key(rank-1); if(rank>0&&rank<=r-l+1) ans[q[i].id]=val; else ans[q[i].id]=-inf; } if(op==5) { int rank=get_rank(p+1); int val=get_key(rank); if(rank>0&&rank<=r-l+1) ans[q[i].id]=val; else ans[q[i].id]=inf; } } for(int i=1;i<=maxq;i++) cout<<ans[i]<<endl; } ```
by koishi_offical @ 2021-06-13 17:12:45


|