zoukankan      html  css  js  c++  java
  • 2020 CCPC Wannafly Winter Camp Day1

    题目链接:K小数查询

    题意:给你一个长度为$n$序列$A$,有$m$个操作,操作分为两种:

    • 输入$x,y,c$,表示对$iin[x,y] $,令$A_{i}=min(A_{i},c)$
    • 输入$x,y,k$,表示询问区间$[x,y]$中的第$k$小数

    思路:数据范围不是很大,可以分块来做,记录每个块已经更新过的最小值$imin[]$,询问时二分答案,然后求出$[x,y]$区间中小于等于$mid$的数的个数$cnt$,通过判断$cnt$与$k$的大小来改变$l,r$即可

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <vector>
    #include <cmath>
    
    using namespace std;
    
    const int N = 100010;
    const int INF = 0x3f3f3f3f;
    
    int block, belong[N], num, l[N], r[N], imin[N];
    int n, m, a[N];
    vector<int> v[N];
    
    void build()
    {
        block = sqrt(n);
        num = n / block;
        if (n % block) num++;
        for (int i = 1; i <= num; i++)
            l[i] = (i - 1) * block + 1, r[i] = i * block;
        r[num] = n;
        for (int i = 1; i <= n; i++)
            belong[i] = (i - 1) / block + 1;
        for (int i = 1; i <= num; i++) {
            imin[i] = INF;
            for (int j = l[i]; j <= r[i]; j++)
                v[i].push_back(a[j]);
            sort(v[i].begin(), v[i].end());
        }
    }
    
    void reset(int x)
    {
        v[x].clear();
        for (int i = l[x]; i <= r[x]; i++) {
            a[i] = min(a[i], imin[x]);
            v[x].push_back(a[i]);
        }
        sort(v[x].begin(), v[x].end());
    }
    
    void update(int x, int y, int c)
    {
        int bl = belong[x], br = belong[y];
        if (bl == br) {
            for (int i = x; i <= y; i++)
                a[i] = min(a[i], c);
            reset(bl);
            return;
        }
        for (int i = x; i <= r[bl]; i++)
            a[i] = min(a[i], c);
        reset(bl);
        for (int i = l[br]; i <= y; i++)
            a[i] = min(a[i], c);
        reset(br);
        for (int i = bl + 1; i < br; i++)
            imin[i] = min(imin[i], c);
    }
    
    int query(int x, int y, int c)
    {
        int bl = belong[x], br = belong[y], cnt = 0;
        if (bl == br) {
            for (int i = x; i <= y; i++)
                if (a[i] <= c || imin[bl] <= c) cnt++;
            return cnt;
        }
        for (int i = x; i <= r[bl]; i++)
            if (a[i] <= c || imin[bl] <= c) cnt++;
        for (int i = l[br]; i <= y; i++)
            if (a[i] <= c || imin[br] <= c) cnt++;
        for (int i = bl + 1; i < br; i++)
            if (imin[i] <= c) cnt = cnt + r[i] - l[i] + 1;
            else cnt = cnt + upper_bound(v[i].begin(), v[i].end(), c) - v[i].begin();
        return cnt;
    }
    
    int ask(int x, int y, int k)
    {
        int l = -1000000000, r = 1000000000;
        while (l < r) {
            int mid = (l + r) / 2;
            if (query(x, y, mid) >= k) r = mid;
            else l = mid + 1;
        }
        return l;
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++)
            scanf("%d", &a[i]);
        build();
        for (int i = 1; i <= m; i++) {
            int kd, x, y, c;
            scanf("%d%d%d%d", &kd, &x, &y, &c);
            if (1 == kd) update(x, y, c);
            else printf("%d
    ", ask(x, y, c));
        }
        return 0;
    }
  • 相关阅读:
    h5移动开发css
    js 小数相加异常
    h5上滑刷新(分页)
    js中的 !!
    图片懒加载(延迟加载)原理及实现
    作用域内优先级及this指针
    函数的属性、方法和构造函数
    判断是否为严格模式
    匿名函数递归调用自身
    闭包
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12229708.html
Copyright © 2011-2022 走看看