「树状数组」[SDOI2009]HH的项链

[SDOI2009]HH的项链

原题链接 [SDOI2009]HH的项链

题目大意

给你 \(n\) 个数,再给你 \(q\) 次询问,每次询问给你 \(l, r\) ,问你 \(l, r\) 中有多少个不同的数

题目题解

分析这道题我们发现,对于一个 \([L_1, R_1]\) 存在另一个 \([L_2, R_1]\) 且 \(L_2\) 严格大于 \(L_1\),那么就一定存在第一个区间不同的数 大于等于 第二个区间的不同的数,这里很显然有一种等于的情况,什么情况等于?在\([L_2,R_1]\) 中包含的数与 \([L_1, L_2 - 1]\) 中包含的数 ,后者的数前者都有。那么我们就发现 对于这样的情况\([L_1, L_2 - 1]\) 中就没有必要存在了。但注意的是,这里我们是严格定义的 \(R_1\)相同 且\(L_1 < L_2\),我们继续推发现\(R_2 > R_1\) 也是符合条件的。

于是我们得到若我们按查询的右区间从小到大排序,这样的就能转化为一个线性的前缀和问题,我们用数据结构来维护每一位上是否为1或0,若为1则说明之后没出现相同的数,若为1则说明出现过,每次处理到查询位的\(R\),然后用数据结构查询 \(sum_R - sum_{l - 1}\) 的值,就能得到我们的答案了

我们这里用树状数组维护,代码如下

//#define fre yes

#include <cstdio>
#include <algorithm>

const int N = 1000005;
struct Node {
    int l, r;
    int pos;
} w[N];
int Vis[N], arr[N], ans[N];
int tree[N];

bool cmp(Node x, Node y) {
    return x.r < y.r;
}

int lowbit(int x) {
    return x & (-x);
}

int n;
void change(int x, int k) {
    while(x <= n) {
        tree[x] += k;
        x += lowbit(x);
    }
}

int sum(int x) {
    int res = 0;
    while(x > 0) {
        res += tree[x];
        x -= lowbit(x);
    } return res;
}

int main() {
    static int q;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &arr[i]);
    }

    scanf("%d", &q);
    for (int i = 1; i <= q; i++) {
        int l, r;
        scanf("%d %d", &l, &r);
        w[i].l = l; w[i].r = r;
        w[i].pos = i;
    }

    std::sort(w + 1, w + 1 + q, cmp);

    int tot = 1;
    for (int i = 1; i <= q; i++) {
        for (int j = tot; j <= w[i].r; j++) {
            if(Vis[arr[j]]) change(Vis[arr[j]], -1);
            change(j, 1);
            Vis[arr[j]] = j;
        }

        tot = w[i].r + 1;
        ans[w[i].pos] = sum(w[i].r) - sum(w[i].l - 1);
    }

    for (int i = 1; i <= q; i++) {
        printf("%d\n", ans[i]);
    } return 0;
}

原文地址:https://www.cnblogs.com/Nicoppa/p/11479310.html

时间: 2024-12-10 15:29:08

「树状数组」[SDOI2009]HH的项链的相关文章

树状数组--P1972 [SDOI2009]HH的项链

题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链变得越来越长. 有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了.于是,他只好求助睿智的你,来解决这个问题. 输入格式 一行一个正整数 n,表示项链长度. 第二行 n 个正整数 ai?,表示项链中第 iii 个贝壳的种类. 第三行一个整数 m,表示 H

csp-s模拟测试56(10.2)Merchant「二分」&#183;Equation「树状数组」

又死了......T1 Merchant 因为每个集合都可以写成一次函数的形式,所以假设是单调升的函数,那么随着t越大就越佳 而单调减的函数,随着t的增大结果越小,所以不是单调的??? 但是我们的单调只需凭借t时刻的sum值是否大于S即可 如果某个单减的集合符合情况,那么他在t==0时就符合情况 如果不符合,那么他就不会作出贡献 所以可以二分 T2 Equation 一开始以为是高斯消元??? 当然不是..... 把每个xi均用x1表示,那么我们发现,对于深度奇偶不同的点,他的表示方式是不同的,

SP3267 DQUERY - D-query(离线树状数组)

给你一个序列,询问一个区间内有多少个不同的数字. 经典离线树状数组,类似于HH(憨憨)的项链,把询问按照右端点排序,保证在每个数字最后一次出现的位置上加1 如果有询问的右端点等于当前加到的数字下标,就对它求一次和并累加进答案,直到所有的查询都被处理. 代码: #include <bits/stdc++.h> #define int long long #define sc(a) scanf("%lld",&a) #define scc(a,b) scanf(&quo

P1972 [SDOI2009]HH的项链

P1972 [SDOI2009]HH的项链 2017-09-18 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不断地收集新的贝壳,因此,他的项链变得越来越长.有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答--因为项链实在是太长了.于是,他只好求助睿智的你,来解决这个问题. 输入输出格式 输入格式: 第一行:一个整数N,表示项链的长度. 第二行:N 个整

[bzoj1878] [SDOI2009]HH的项链(树状数组+离线)

1878: [SDOI2009]HH的项链 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 3210  Solved: 1619[Submit][Status][Discuss] Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变得越来越长.有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的

loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

$ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinobu 早有准备,Alice.Ayaya.Karen.Shinobu.Yoko 五人又能继续愉快地玩耍啦! 「噢--!不是有放上天的烟花嘛!」Karen 兴奋地喊道. 「啊等等--」Yoko 惊呼.Karen 手持点燃引信的烟花,「嗯??」 Yoko 最希望见到的是排列优美的烟火,当然不会放过这个机会-

「ZJOI2017」树状数组

「ZJOI2017」树状数组 以下均基于模2意义下,默认\(n,m\)同阶. 熟悉树状数组的应该可以发现,这题其实是求\(l-1\)和\(r\)位置值相同的概率. 显然\(l=1\)的情况需要特盘. 大暴力 对于\(l=1\)的情况,可以发现一个操作不会产生影响当且仅当增加\(r\)的值,而其他情况会改变\(l-1\)或\(r\). 对于\(l!=1\)的情况: ? 针对一次修改区间\([ql,qr]\). \([ql,qr]\)包含\(l-1,r\),那么有\(\displaystyle 2

【树状数组】Bzoj1878[SDOI2009] HH的项链

Description HH有一串由各种漂亮的贝壳组成的项链.HH相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH不断地收集新的贝壳,因此, 他的项链变得越来越长.有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答...因为项链实在是太长了.于是,他只好求助睿智的你,来解 决这个问题. Input 第一行:一个整数N,表示项链的长度. 第二行:N个整数,表示依次表示项链中贝壳的编号(编号为0到1000000之间的

BZOJ1878 SDOI2009 HH的项链 树状数组

题意:给定一个颜色序列,每组询问给出区间[l,r],求[l,r]中不同颜色的数量 题解: 首先把所有颜色离散化,然后离线,将询问按右区间升序排列.从1-N把整个序列扫一遍,设Pos[i]为第i个颜色最后出现的位置,假定当前扫到的位置为i,则更新Pos[a[i]],那么问题变成了:求一个序列(Pos)中,大于等于一个数(L)的数的数量. 用树状数组维护Pos=j的数的数量,每次查询树状数组中L-N的和即可. 貌似SDOI不喜欢考大型数据结构啊……坐等今年打脸 #include <cstdio>