zoukankan      html  css  js  c++  java
  • Charging

    https://ac.nowcoder.com/acm/contest/13175/C

    数轴上有[1,n]一共n个点,m个区间分别是[li,ri]。
    tot为所选取的区间数量,x为所有所选取的区间的交集长度。
    min(tot,x)的最大值。

    尺取法

    题意即是尽可能多的段同时重复段尽量长

    所选的区间左端点一定是某区间的左端点

    所取的区间右端点也是

    先按左端点排序区间,让所选的个数小于等于交集的长度,

    如果大了就去掉最前面的区间

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N = 3e5 + 7;
    pair<int,int> a[N];
    int n,m;
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;++i)
            scanf("%d%d",&a[i].first,&a[i].second);
        sort(a+1,a+1+m);
        ll ans=0,cnt=0;
        priority_queue<int, vector<int>, greater<int> > q;
        for(int i=1;i<=m;++i){
            q.push(a[i].second);
            ++cnt;
            while(cnt>q.top()-a[i].first+1){
                q.pop();
                --cnt;
            }
            ans=max(ans,cnt);
           // cout<<"==="<<cnt<<"
    ";
        }
        cout<<ans<<"
    ";
        return 0;
    }

    二分答案

    nlognlogn+mlogm

    #include <bits/stdc++.h>
    #define sc(x) scanf("%d", &(x))
    #define pr(x) printf("%d
    ", (x))
    using namespace std;
    typedef pair<int, int> pii;
    const int N = 3e5 + 7;
    #define lowbit(x) ((x) & (-x))
    int tree[N];
    inline void add(int i) {
        for (int pos = i; pos < N; pos += lowbit(pos)) ++tree[pos];
    }
    inline int query(int n) {
        int ans = 0;
        for (int pos = n; pos; pos -= lowbit(pos)) ans += tree[pos];
        return ans;
    }
    pii a[N];
    int main() {
        int n, m;
        sc(n), sc(m);
        for (int i = 0; i < m; ++i) sc(a[i].first), sc(a[i].second);
        sort(a, a + m);
        int ans = 0;
        for (int L = 1, p = 0; L <= n; ++L) {
            while (p < m && a[p].first <= L) add(a[p++].second);
            int left = L, right = n, R = 0;
            while (left <= right) {
                int mid = left + right >> 1;//选取区间的右端点 
                int tot = p - query(mid - 1);//减去不满足我们枚举出的交集的点 
                if (tot >= mid - L + 1)//尝试扩大区间 
                    left = mid + 1, R = mid;
                else
                    right = mid - 1;
            }
            ans = max(ans, R - L + 1);
        }
        pr(ans);
        return 0;
    }
  • 相关阅读:
    leetcode203
    leetcode88
    leetcode219
    leetcode225
    2018-12-25-C#-使用转换语义版本号
    2018-12-25-C#-使用转换语义版本号
    2018-10-15-Winforms-可能遇到的-1000-个问题
    2018-10-15-Winforms-可能遇到的-1000-个问题
    2018-8-10-UWP-WPF-解决-xaml-设计显示异常
    2018-8-10-UWP-WPF-解决-xaml-设计显示异常
  • 原文地址:https://www.cnblogs.com/PdrEam/p/14604422.html
Copyright © 2011-2022 走看看