Educational Codeforces Round 87 (Rated for Div. 2)D. Multiset(树状数组+二分)

题目:click
题意:在这里插入图片描述
一开始multiset卡内存了,发现直接二分加树状数组就可以了。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int MAXN=262144*2+10;
const double PI=acos(-1.0);
const long double eps=1e-9;
const int MAX=4e4+5;
int c[1000100];
int n;
multiset<int>hh;
inline int lowbit(int x)
{
    return x&(-x);
}
inline ll query(int x)
{
    ll ans=0;
    for(int i=x;i>0;i-=lowbit(i))
        ans+=c[i];
        return ans;
}
inline void add(int x,int val)
{
    for(int i=x;i<=n;i+=lowbit(i))
        c[i]+=val;
        return ;
}
int main()
{
    int q,i,j;
    scanf("%d %d",&n,&q);
    for(i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        add(x,1);
    }
    for(i=0;i<q;i++)
    {
        int x;
        scanf("%d",&x);
        if(x>=1)
        {
            add(x,1);
            continue;
        }
        x=-x;
        int l=1,r=n;
        int temp;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(query(mid)>=x)
            {
                r=mid-1;
            }
            else
                l=mid+1;
        }
        add(l,-1);
    }
    for(i=1;i<=n;i++)
    {
        if(c[i])
        {
            printf("%d",i);
            return 0;
        }
    }
    printf("0");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43958964/article/details/106258210