Codeforces Round #724 (Div. 2) D - Omkar and Medians 树状数组+离散化

11 篇文章 0 订阅
2 篇文章 0 订阅

原题链接
题意:
已知一个数组a和数组b,bi是a数组中前i个元素的中位数,现在给定b数组,判断是否可以求出a数组

思路:
假设第b[i]前都满足,那么说明此时b[i]就是a数组中的中位数,现在插入b[i+1]会出现两种情况。
1.如果b[i+1]和b[i]之间没有出现过数,那么只要插入一个b[i+1]再根据大小关系插入一个+inf或者-inf就行了2.如果b[i+1]和b[i]之间出现过数,那么仅插入两个数最多只能使中位数移动一位,并不能移到b[i+1]身上,所以这种情况是不行的。

所以直接树状数组查询中间有没有数字出现过就可以了。

#include<bits/stdc++.h>
#define LL long long
#define INF INT64_MAX
#define MOD 998244353
#define ls rt << 1
#define rs rt << 1 | 1
using namespace std;
typedef pair<int,int>pa;
const int N = 3e5+7;
int a[N], n, tr[N], vis[N];
char s[N];
vector<int>v;
int lowbit(int x){return x&(-x); };
void update(int x){
    for(int i = x;i <= n;i+=lowbit(i)){
        tr[i] += 1;
    }
}
int query(int x){
    int res = 0;
    for(int i = x;i >= 1;i-=lowbit(i)){
        res += tr[i];
    }
    return res;
}
int main(){
    int _;
    scanf("%d", &_);
    while(_--){
        v.clear();
        scanf("%d", &n);
        for(int i = 1;i <= n;i++){
            vis[i] = 0;
            scanf("%d", &a[i]);
            v.push_back(a[i]);
        }
        memset(tr, 0, sizeof(tr));
        sort(v.begin(), v.end());
        v.erase(unique(v.begin(), v.end()), v.end());
        for(int i = 1;i <= n;i++){
            a[i] = lower_bound(v.begin(), v.end(), a[i])-v.begin()+1;
        }
        int t1, t2, fla = 0;
        update(a[1]);
        for(int i = 2;i <= n;i++){
            if(a[i]==a[i-1]){
                update(a[i]);
                continue;
            }
            if(a[i]>a[i-1]) t2 = query(a[i]-1), t1 = query(a[i-1]);
            else t2 = query(a[i-1]-1), t1 = query(a[i]);
            if(t2-t1){
                fla = 1;
                break;
            }
            update(a[i]);
        }
        if(fla) printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值