zoukankan      html  css  js  c++  java
  • JZOJ 1078. 【GDOI2006】The Kth Element

    \(\text{Problem}\)

    给定一个整数序列 \(a[1..N]\),定义 \(sum[i][j]=a[i]+a[i+1]+...+a[j]\),将所有的 \(sum[i][j]\) 从小到大排序(其中 \(i,j\) 满足 \(1<=i<=j<=N\) ),得到一个长为 \(N*(N+1)/2\) 的序列,求该序列中的第 \(K\) 个元素。

    \(\text{Solution}\)

    非常经典的题
    二分答案然后 \(check\)

    \(\text{Code}\)

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #define ls (p << 1)
    #define rs (ls | 1)
    #define RE register
    #define IN inline
    using namespace std;
    typedef long long LL;
    
    const int N = 2e4 + 5;
    const LL INF = 1e18;
    int n, m, len;
    LL a[N], b[N], sum[N * 4];
    
    void build(int p, int l, int r)
    {
    	sum[p] = 0;
    	if (l == r) return;
    	int mid = l + r >> 1;
    	build(ls, l, mid), build(rs, mid + 1, r);
    }
    void Modify(int p, int l, int r, int x, int v)
    {
    	if (x > r || x < l) return;
    	if (l == r) return sum[p] += v, void();
    	int mid = l + r >> 1;
    	if (x <= mid) Modify(ls, l, mid, x, v);
    	else Modify(rs, mid + 1, r, x, v);
    	sum[p] = sum[ls] + sum[rs];
    }
    LL Query(int p, int l, int r, int x)
    {
    	if (x > r || x < l) return 0;
    	if (l == r) return sum[p];
    	int mid = l + r >> 1;
    	if (x <= mid) return Query(ls, l, mid, x) + sum[rs];
    	return Query(rs, mid + 1, r, x);
    }
    
    IN int check(LL mid)
    {
    	int res = 0;
    	build(1, 1, len), Modify(1, 1, len, lower_bound(b + 1, b + len + 1, 0) - b, 1);
    	for(RE int i = 1; i <= n; i++)
    	{
    		int x = lower_bound(b + 1, b + len + 1, a[i] - mid) - b;
    		res += Query(1, 1, len, x);
    		Modify(1, 1, len, lower_bound(b + 1, b + len + 1, a[i]) - b, 1);
    	}
    	return res >= m;
    }
    
    int main()
    {
    	scanf("%d%d", &n, &m);
    	for(RE int i = 1; i <= n; i++) scanf("%lld", &a[i]), a[i] += a[i - 1], b[i] = a[i];
    	b[n + 1] = 0, sort(b + 1, b + n + 2), len = unique(b + 1, b + n + 2) - b - 1;
    	LL l = -INF, r = INF, mid, ans;
    	while (l <= r)
    	{
    		mid = (l + r) >> 1;
    		if (check(mid)) ans = mid, r = mid - 1;
    		else l = mid + 1;
    	}
    	printf("%lld\n", ans);
    }
    
  • 相关阅读:
    正则中[A-z]与[A-Za-z]的区别
    .Net Core 缓存方式(二)DistributedSqlServerCache实现(2)
    .Net Core 缓存方式(二)分布式缓存及MemoryDistributedCache 实现(1)
    anaconda安装后spyder打不开的解决方法
    Pandas
    CrawlSpider、分布式、增量式
    Scrapy之数据解析与数据持久化存储
    封装axios库
    vue全国省市选择vue组件
    html+jq实现全国省的单选,弹框输入input
  • 原文地址:https://www.cnblogs.com/leiyuanze/p/15822186.html
Copyright © 2011-2022 走看看