我是靠谱客的博主 积极酸奶,最近开发中收集的这篇文章主要介绍P4062 [Code+#1]Yazid 的新生舞会(线段树做法),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

P4062 [Code+#1]Yazid 的新生舞会(线段树做法)

题意:

给你一个序列a[1…n]​,求存在绝对众数的子区间个数。

绝对众数指:区间中出现次数最多的那个数,出现次数严格大于区间长度的一半。

题解:

这两个博客将的很长清楚明白(尤其是第一个),我在反复看了n遍后,终于明白。题目细节很多,我再怎么写也没这两个详细,干脆直接放上链接。
Zechariah的博客
OMG_wc 的博客
关于题解中提到的三阶前缀和:
三阶前缀和公式转换:
图来自lx_tyin博客
在这里插入图片描述

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const LL mod = 1e9 + 7;
const int N = 500005;
// 修改差分 来维护前缀和的前缀和
// c1 为差分d c2为d*i  c3 为d*i*i
LL c1[N * 2], c2[N * 2], c3[N * 2];
LL sum(int x) {
    LL res = 0;
    for (int i = x; i > 0; i -= i & -i) {
        res += c1[i] * (x + 2) * (x + 1) - c2[i] * (2 * x + 3) + c3[i];
    }
    return res / 2;
}
void add(int x, LL d, int n) {
    for (int i = x; i <= n; i += i & -i) {
        c1[i] += d;
        c2[i] += d * x;
        c3[i] += d * x * x;
    }
}
int a[N];
vector<int> b[N];
int main() {
    int n;
    scanf("%d%*d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        b[a[i]].push_back(i);
    }
    const int wc = n + 1;  // 偏移量,把[-n,n] 平移到 [1,2n+1]
    LL ans = 0;
    for (int i = 0; i < n; i++) {
        b[i].push_back(n + 1);
        int last = 0;
        for (int j = 0; j < b[i].size(); j++) {
        	//j表示i的个数
            int y = 2 * j - last + wc;
            int x = 2 * j - (b[i][j] - 1) + wc;
            // 查询 sum([1,t-1] 的权值和), 其中t在[x,y]范围内,
            ans += sum(y - 1) - (x >= 3 ? sum(x - 2) : 0);
            // [x,y] 这些数的权值+1
            add(x, 1, 2 * n + 1);
            add(y + 1, -1, 2 * n + 1);
            last = b[i][j];
        }
        
        //撤销操作
        last = 0;
        for (int j = 0; j < b[i].size(); j++) {
            int y = 2 * j - last + wc;
            int x = 2 * j - (b[i][j] - 1) + wc;
            add(x, -1, 2 * n + 1);
            add(y + 1, 1, 2 * n + 1);
            last = b[i][j];
        }
    }
    printf("%lldn", ans);
    return 0;
}

最后

以上就是积极酸奶为你收集整理的P4062 [Code+#1]Yazid 的新生舞会(线段树做法)的全部内容,希望文章能够帮你解决P4062 [Code+#1]Yazid 的新生舞会(线段树做法)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(30)

评论列表共有 0 条评论

立即
投稿
返回
顶部