• BZOJ5321 JXOI2017加法(二分答案+贪心+堆+树状数组)


      二分答案后得到每个位置需要被加的次数。考虑贪心。从左到右考虑每个位置,将以该位置为左端点的区间按右端点从大到小加进堆。看该位置还需要被加多少次,如果不需要加了就不管,否则取堆顶区间将其选择,BIT实现区间覆盖。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    using namespace std;
    #define ll long long
    #define N 200010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int T,n,m,k,a[N],c[N],tree[N];
    priority_queue<int> q;
    vector<int> b[N];
    void add(int k,int x){while (k<=n) tree[k]+=x,k+=k&-k;}
    int query(int k){int s=0;while (k) s+=tree[k],k-=k&-k;return s;}
    bool check()
    {
        for (int i=1;i<=n;i++) tree[i]=0;int cnt=0;
        while (!q.empty()) q.pop();
        for (int i=1;i<=n;i++) add(i,c[i]-c[i-1]);
        for (int i=1;i<=n;i++)
        {
            for (int j=0;j<b[i].size();j++) q.push(b[i][j]);
            int x=query(i);
            for (;x>0;x--)
            {
                if (q.empty()) return 0;
                int y=q.top();q.pop();
                if (y<i) return 0;
                add(i,-1),add(y+1,1);
                if ((++cnt)>k) return 0;
            }
        }
        return 1;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj5321.in","r",stdin);
        freopen("bzoj5321.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        T=read();
        while (T--)
        {
            n=read(),m=read(),k=read();int p=read();
            int l=100000000,r,ans;
            for (int i=1;i<=n;i++) l=min(l,a[i]=read()),b[i].clear();
            for (int i=1;i<=m;i++)
            {
                int x=read(),y=read();
                b[x].push_back(y);
            }
            r=l+m*p;
            while (l<=r)
            {
                int mid=l+r>>1;
                for (int i=1;i<=n;i++) c[i]=mid<=a[i]?0:(mid-a[i]-1)/p+1;
                if (check()) l=mid+1,ans=mid;
                else r=mid-1;
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Linux install
    plafrom library
    lua 线程
    plafrom SDK
    CSS中的focus-within伪类选择器
    网站打开速度优化_如何提高网页访问速度技巧方法总结
    网页预加载_骨架屏Skeleton Screen的实现
    SASS简介及使用方法
    什么是BFC布局——浅析BFC布局的概念以及作用
    JAVA面试题(九):JVM
  • 原文地址:https://www.cnblogs.com/Gloid/p/10076028.html
Copyright © 2020-2023  润新知