AtCoder Beginner Contest 247(E - Max Min)

AtCoder Beginner Contest 247(E - Max Min)

原题链接:

E - Max Min

题意:

原题

给你一个长度为N的序列A和两个数字 X X X Y Y Y,问有多少个 [ L , R ] [L, R] [L,R]满足:

  • 1 < = L < = R < = N 1<=L<=R<=N 1<=L<=R<=N
  • m a x ( A L − R max(A_{L-R} max(ALR) = X X X, m i n ( A L − R min(A_{L-R} min(ALR) = Y Y Y
  • 数据范围 N , A i , X , Y N, A_{i}, X, Y N,Ai,X,Y 均为 1 − 2 ∗ 1 0 5 1-2*10^{5} 12105

思路参考题解

  • 首先对于序列中大于X和小于Y的数字一定是不能够包含在区间 [ L , R ] [L, R] [L,R]内的,据此可以根据将原序列分为若干个子序列 B B B,这样子序列内的数字大小全部都是在 [ X , Y ] [X, Y] [X,Y]内的,然后对这些子序列操作求解即可。
  • 对于每一个子序列 B B B,该怎么求解有多少个区间中同时包含 X , Y X, Y X,Y呢,或许包含的不止一对,直接求解是不容易计算的,容斥原理,这时可以想到求解他的反例,即有多少区间只包含 X X X,有多少区间只包含 Y Y Y,或者有多少区间是 X , Y X, Y X,Y都不包含的。
    我们想要找到的是“包含两者”的子序列的数量X和Y."可以表示如下:
    (所有序列) −(不包含 X 的序列) −(不包含 Y 的序列) + (既不包含 X 也不包含 Y 的序列)。
const int N = 2e5+100;
int __[N], X_[N], _Y[N], XY[N];
int n;
ll f(int a[]) {
    ll s = 0, t = 0;
    for(int i = 1; i <= n; i++) {
        if(a[i]) s += (t + 1) * t / 2, t = 0;
        else t ++;
    }
    s += (t + 1) * t / 2;
    return s;
}
void solve(){
    int x, y; cin >> n >> x >> y;
    vector<int> v(n + 1);
    for(int i = 1; i <= n; i++) cin >> v[i];
    for(int i = 1; i <= n; i++) {
        if(!(v[i] >= y && v[i] <= x)) __[i] = X_[i] = _Y[i] = XY[i] = 1;
        if(v[i] == x) X_[i] = XY[i] = 1;
        if(v[i] == y) _Y[i] = XY[i] = 1;
    }

    ll re = f(__) - f(X_) - f(_Y) + f(XY);
    cout << re << '\n';
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值