zoukankan      html  css  js  c++  java
  • CF484E Sign on Fence

    题意

    给定一个长度为n的数列,有m次询问,询问形如l r k
    要你在区间[l,r]内选一个长度为k的区间,求区间最小数的最大值

    Sol

    二分答案
    怎么判定,每种数字开一棵线段树
    某个位置上的数大于等于它为1
    那么就是求区间最大的1的序列长度大于k
    二分的最优答案一定在这个区间内,否则不优
    排序后就是用主席树优化空间
    之前(build)一下,因为区间有长度不好赋值

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(1e5 + 5);
    const int __(2e6 + 5);
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, m, tot, rt[_], a[_], id[_], ls[__], rs[__], o[_], len;
    struct Data{
    	int maxl, maxr, maxn, len;
    
    	IL void Init(){
    		maxl = maxr = maxn = len = 0;
    	}
    } T[__], Ans;
    
    IL int Cmp(RG int x, RG int y){
    	return a[x] < a[y];
    }
    
    IL Data Merge(RG Data A, RG Data B){
    	RG Data ret;
    	ret.maxl = A.maxl, ret.maxr = B.maxr, ret.len = A.len + B.len;
    	ret.maxn = max(A.maxr + B.maxl, max(A.maxn, B.maxn));
    	if(A.maxl == A.len) ret.maxl = A.len + B.maxl;
    	if(B.maxr == B.len) ret.maxr = B.len + A.maxr;
    	return ret;
    }
    
    IL void Modify(RG int &x, RG int l, RG int r, RG int p){
    	ls[++tot] = ls[x], rs[tot] = rs[x], T[tot] = T[x], x = tot;
    	if(l == r){
    		T[x].maxl = T[x].maxr = T[x].maxn = 1;
    		return;
    	}
    	RG int mid = (l + r) >> 1;
    	if(p <= mid) Modify(ls[x], l, mid, p);
    	else Modify(rs[x], mid + 1, r, p);
    	T[x] = Merge(T[ls[x]], T[rs[x]]);
    }
    
    IL void Query(RG int x, RG int l, RG int r, RG int L, RG int R){
    	if(L <= l && R >= r){
    		Ans = Merge(Ans, T[x]);
    		return;
    	}
    	RG int mid = (l + r) >> 1;
    	if(L <= mid) Query(ls[x], l, mid, L, R);
    	if(R > mid) Query(rs[x], mid + 1, r, L, R);
    }
    
    IL void Build(RG int &x, RG int l, RG int r){
    	T[x = ++tot].len = r - l + 1;
    	if(l == r) return;
    	RG int mid = (l + r) >> 1;
    	Build(ls[x], l, mid), Build(rs[x], mid + 1, r);
    }
    
    int main(RG int argc, RG char* argv[]){
    	n = Input();
    	for(RG int i = 1; i <= n; ++i) id[i] = i, o[i] = a[i] = Input();
    	sort(id + 1, id + n + 1, Cmp), sort(o + 1, o + n + 1);
    	len = unique(o + 1, o + n + 1) - o - 1;
    	Build(rt[len + 1], 1, n);
    	for(RG int i = len, j = n; i; --i){
    		rt[i] = rt[i + 1];
    		for(; j && a[id[j]] == o[i]; --j)
    			Modify(rt[i], 1, n, id[j]);
    	}
    	m = Input();
    	for(RG int i = 1; i <= m; ++i){
    		RG int l = Input(), r = Input(), k = Input();
    		RG int L = 1, R = len, ans = 0;
    		while(L <= R){
    			RG int mid = (L + R) >> 1;
    			Ans.Init();
    			Query(rt[mid], 1, n, l, r);
    			if(Ans.maxn >= k) ans = mid, L = mid + 1;
    			else R = mid - 1;
    		}
    		printf("%d
    ", o[ans]);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    java图片压缩 、图片缩放,区域裁剪,水印,旋转,保持比例。
    java树形菜单实现
    vue-resource的使用,前后端数据交互
    如何在IntelliJ IDEA中使用.ignore插件忽略不必要提交的文件
    Git以及TortoiseGit的下载安装使用
    springBoot总结
    idea如何设置类头注释和方法注释
    (document).height()与$(window).height()
    使用js对中文进行gbk编码
    JS中URL编码参数(UrlEncode)
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8489731.html
Copyright © 2011-2022 走看看