牛客练习赛72 B brz的雪糕 前缀和

前缀和brz的雪糕

解题思路

用前缀和数组解题, t b [ i ] tb[i] tb[i] 保存从起始位置到第 i i i 个位置的愉悦值。这里讲思路的时候默认位置从 1 1 1 开始。

查询的时候,假设区间是 [ a , b ] [a, b] [a,b],分两种情况:

  • a = 1 a=1 a=1。值直接为 t b [ b ] tb[b] tb[b]

  • a > = 2 a >= 2 a>=2。这时候要进行判断了,一般情况下值直接是 t b [ b ] − t b [ a − 1 ] tb[b] - tb[a - 1] tb[b]tb[a1](等价于 t b [ b ] − t b [ a ] + 1 tb[b] - tb[a] + 1 tb[b]tb[a]+1) 。

    但有个特殊情况: t b [ a ] = t b [ a − 1 ] tb[a]=tb[a-1] tb[a]=tb[a1],也就是说 a a a 位置和 a − 1 a-1 a1 位置的数是一样的,之前处理前缀和的时候位置 a a a 相当于没有加 1 1 1

    但是现在 a a a 位置变成了第一个位置的数,需要加 1 1 1,那就相当于现在少加了个 1 1 1,所以这种时候值在原来的基础上加 1 1 1 即可。

参考代码

写的时候数组下标从 0 0 0 开始的,与题给区间要记得转换一下(如 a a a 对应数组中的下标 a − 1 a-1 a1 )。

#include<bits/stdc++.h>
using namespace std;
//#define LOCAL  //提交的时候一定注释
#define _for(i, a, b) for(int i = (a); i < (b); ++i)
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define pb push_back
#define VI vector<int>
//#define maxn 1e2+10
#define INF 0x3f3f3f3f
#define mp make_pair
typedef long long LL;
typedef double db;
const double eps = 1e-6;  //定义浮点数误差
const int MOD = 998244353;
const int maxn = 2000010;

int readint(){
    
    
    int x; scanf("%d", &x); return x;
}

int tb[maxn];

int main() {
    
    
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n, k, q;
    scanf("%d%d%d", &n, &k, &q);
    VI x;
    _for(i, 0, n) {
    
    
        x.pb(readint());
    }
    int pre = 1;
    tb[0] = pre;
    _for(j, 1, x.size()) {
    
    
        pre += (x[j] != x[j - 1]) ? 1 : 0;
        tb[j] = pre;  //处理前缀和数组
    }

    _for(i, 0, q) {
    
    
        int sum, a, b;
        scanf("%d%d", &a, &b);
        if (a - 2 >= 0) {
    
    
            sum = tb[b - 1] - tb[a - 2];
            if (x[a - 1] == x[a - 2]) sum++;
        }
        else   //a = 1的时候,直接取tb的值
            sum = tb[b - 1];
        printf("%s\n", (sum >= k) ? "Yes" : "No");
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/Encore47/article/details/109542068