CF484E. Sign on Fence(主席树+二分)

it2024-12-30  40

CF484E. Sign on Fence

CF484E. Sign on Fence

题目大意

给你n块木板,每块木板有高度Hi,q次询问每次询问在[l,r]区间中最大的长度为w的区间的最小值。

思路

将木板从大到小排序,建动态开点线段树维护区间最长子段,于是就可以二分高度,判断这个高度在[l,r] 区间中存不存在长度大等于w的子段。

代码

#include <bits/stdc++.h> using namespace std; #define dd(x) cout<<#x<<" = "<<x<<" " #define rep(i,a,b) for(int i=(a);i<(b);i++) #define de(x) cout<<#x<<" = "<<x<<"\n" #define mes(p) memset(p,0,sizeof(p)) #define fi first #define se second #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define sz(x) (int)x.size() #define pb push_back #define all(x) x.begin(),x.end() const int maxn=100005; const int mod = 1e9+7; const int M = 3e5; typedef long long ll; typedef vector <int > vi; typedef pair<int ,int > pi; bool cmp(const pi&a,const pi&b){return a.fi>b.fi;} pi a[maxn]; int n,q,cnt, T[maxn]; struct node { int ls,rs,l,r,s; node (){ls=rs=l=r=s=0;} }t[maxn<<5]; void push_up(int rt,int m){ int ls=t[rt].ls, rs = t[rt].rs; int rm = m>>1, lm = m-rm; t[rt].l = t[ls].l; if(t[ls].l == lm) t[rt].l += t[rs].l; t[rt].r = t[rs].r; if(t[rs].r == rm) t[rt].r += t[ls].r; t[rt].s = max(t[rs].l+t[ls].r,max(t[rs].s,t[ls].s)); return ; } void update(int pre,int &now,int pos,int l,int r){ now = ++cnt; if(l==r){ t[now].l = t[now].r = t[now].s = 1; return ; } t[now].ls = t[pre].ls; t[now].rs = t[pre].rs; int mid = l+r>>1; if(pos <=mid) update(t[pre].ls,t[now].ls,pos,l,mid); else update(t[pre].rs,t[now].rs,pos,mid+1,r); push_up(now,r-l+1); } node qry(int now,int L,int R,int l,int r){ if(L<=l && r<=R){ return t[now]; } int mid = l+r>>1, m=r-l+1, rm=m>>1, lm=m-rm; node ls,rs,ans; if(L <= mid) ls = qry(t[now].ls,L,R,l,mid); if(R > mid) rs = qry(t[now].rs,L,R,mid+1,r); ans.l = ls.l; if(ls.l == lm) ans.l+=rs.l; ans.r = rs.r; if(rs.r == rm) ans.r+=ls.r; ans.s = max(ls.r+rs.l,max(ls.s,rs.s)); return ans; } int check(int l,int r,int h,int rt){ if(qry(T[rt],l,r,1,n).s >= h) return 1; return 0; } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cin >> n; rep(i,1,n+1) cin >> a[i].fi , a[i].se = i; sort(a+1,a+n+1,cmp); rep(i,1,n+1){ update(T[i-1],T[i],a[i].se,1,n); } cin>> q; while(q--){ int x, y ,m; cin >> x >> y >> m; int l=1,r=n; while(l<=r){ int mid = l+r>>1; if(check(x,y,m,mid)) r=mid-1; else l=mid+1; } r++; cout << a[r].fi << endl; } return 0; }

转载于:https://www.cnblogs.com/seast90/p/10836232.html

相关资源:数据结构—成绩单生成器
最新回复(0)