首页 > 其他分享 >P1972 [SDOI2009] HH的项链

P1972 [SDOI2009] HH的项链

时间:2024-08-12 17:17:05浏览次数:8  
标签:ft int lowbit pos long HH const SDOI2009 P1972

https://www.luogu.com.cn/problem/P1972

莫队算法被卡,只能得60points

正解有点像基于贪心的fenwick tree策略
fenwick的每个位置表示当前位置上是否是某个数的最后一次出现位置,值为0或者1

右指针升序排序,然后右指针移动过程中更新每个数最后一次出现的位置
而不管左指针如何变,只要保证右指针是非递减的,就可以直接使用区间查询来得到区间中不同元素的数量了

/*
* FenwickTree(树状数组)
* 设计思想:基于二进制表示的下标的快速变换来实现前缀和的计算,适用于差分后的区间修改单点查询,单点修改区间查询。
* 基于面向对象的编程思想,本方法尽可能多的隐藏了内部实现的细节,并且将必要的编程接口暴露在外部,并需要对这些接口进行直接的修改。
* 在该设计中,基础的方法都已实现,如有需要用户可以自行在该结构上进行改进。
*
* gitHub(仓库地址): https://github.com/yxc-s/programming-template.git
*/










/*
该树总是约定区间左端点从1开始(避免lowbit(0)的情况)。
如果已有数组,建议使用已有的数组实例化对象,时间复杂度更低。
注意初始化数组时容器为int和longlong的区别。
*/

class FenwickTree {
public:
    /* 按区间最大右端点下标构造。*/
    FenwickTree(unsigned int n) : n_(n) {
        ft_.resize(n_);
    }

    /* 基于已有的数组构造。*/
    FenwickTree(const std::vector<long long>& f) {
        n_ = static_cast<int>(f.size());
        ft_.assign(n_, 0);
        for (int i = 1; i < n_; ++i) {
            ft_[i] += f[i];
            if (i + lowbit(i) < n_) {
                ft_[i + lowbit(i)] += ft_[i];
            }
        }
    }

    /* 移动构造,减少一次资源分配 */
    FenwickTree(std::vector<long long>&& f) {
        n_ = static_cast<int>(f.size());
        ft_ = std::move(f);
        for (int i = 1; i < n_; ++i) {
            if (i + lowbit(i) < n_) {
                ft_[i + lowbit(i)] += ft_[i];
            }
        }
    }

    /* 按数组元素出现频次构造*/
    FenwickTree(const std::vector<int>& s) {
        n_ = *std::max_element(s.begin() + 1, s.end()) + 1;
        ft_.resize(n_);
        for (size_t i = 1; i < s.size(); ++i) {
            ft_[s[i]]++;
            if (s[i] + lowbit(s[i]) < n_) {
                ft_[s[i] + lowbit(s[i])] += ft_[s[i]];
            }
        }
    }

    /* 单点更新。 */
    void update(int pos, long long value) {
        assert(pos > 0);
        while (pos < n_) {
            ft_[pos] += value;
            pos += lowbit(pos);
        }
    }

    /* 区间更新。*/
    void update(int l, int r, long long value) {
        assert(l > 0 && r >= l);
        update(l, value);
        update(r + 1, -value);
    }

    /* 单点查询。*/
    long long query(int p) {
        assert(p < n_);
        long long res = 0;
        while (p > 0) {
            res += ft_[p];
            p -= lowbit(p);
        }
        return res;
    }

    /* 区间查询。*/
    long long query(int l, int r) {
        assert(l <= r);
        return query(r) - query(l - 1);
    }


private:
    int n_;
    std::vector<long long>  ft_;


private:
    int lowbit(int x) const noexcept{ return (x & (-x)); }
};



using namespace std;
inline void preProcess() {

}


void solve(){
    int n;
    cin >> n;

    vector<int> a(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }

    int m;
    cin >> m;
    vector<pair<int, int>> querys(m);

    for (int i = 0; i < m; ++i) {
        cin >> querys[i].first >> querys[i].second;
    }

    vector<int> pos(m);
    iota(pos.begin(), pos.end(), 0);
    
    sort(pos.begin(), pos.end(), [&](const int i, const int j) {
        return querys[i].second < querys[j].second;
    });

    int s = *max_element(a.begin() + 1, a.end());
    FenwickTree ft(n + 1);
    vector<int> vis(s + 1, -1);
    int r = 0;
    vector<int> ans(m);
    for (const auto& idx : pos) {
        const auto&[x, y] = querys[idx];
        while (r < y) {
            r ++;
            if (vis[a[r]] == -1){    
                ft.update(r, 1);
            }
            else {
                ft.update(vis[a[r]], -1);
                ft.update(r, 1);
            }
            vis[a[r]] = r;
        }
        ans[idx] = ft.query(y) - ft.query(x - 1);
    }

    for (const auto& x : ans) {
        cout << x << '\n';
    }
}

标签:ft,int,lowbit,pos,long,HH,const,SDOI2009,P1972
From: https://www.cnblogs.com/yxcblogs/p/18355379

相关文章

  • Linux服务器配置SHH免密互通
    服务器A172.25.11.11,服务器B172.25.11.12在服务器A上配置假设服务器A的IP地址为172.25.11.11,我们将在这台服务器上生成密钥对并将公钥复制到服务器B上。生成密钥对:打开终端,执行以下命令生成密钥对。在生成过程中,你可以选择保留默认路径和设置空密码以简化使用,也可......
  • GraphHopper路劲规划导航(Android源码调试运行)
    本文主要记录在运行graphhopper安卓版路径规划导航源码的步骤和遇到的问题。成功运行了程序,但是路劲规划一直不成功,问题一开始是服务地址,后来又是key的问题,在这个项目中涉及到了graphhopper、mapbox、mapilion的key,mapbox带导航的key我一直无法获取。目前最大的问题:我无法......
  • 分类预测|基于HHO-CNN-BiLSTM-Attention的数据分类预测Matlab程序 多特征输入多类别输
    分类预测|基于HHO-CNN-BiLSTM-Attention的数据分类预测Matlab程序多特征输入多类别输出文章目录分类预测|基于HHO-CNN-BiLSTM-Attention的数据分类预测Matlab程序多特征输入多类别输出前言:HHO-CNN-BiLSTM-Attention流程一、哈里斯鹰优化HHO二、数据展示三、核心代码......
  • Google RichHF-18K 文本到图像生成中的丰富人类反馈
      每周跟踪AI热点新闻动向和震撼发展想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领域的领跑者。点击订阅,与未来同行!订阅:https://......
  • [SDOI2009] HH去散步
    [SDOI2009]HH去散步设\(dp_{i_j}\)表示第\(i\)个时刻,走到第\(j\)条边的终点的方案数转移:从当前点\(u\)开始,枚举从\(u\)出发的所有点,向\(dp_{i+1,to_u}\)转移但是\(t\)非常大,所以需要使用矩阵快速幂设初始矩阵为\(\text{A}\),转移矩阵为\(\text{B}\),那么答案矩......
  • 探索Java编程的深邃宇宙 —— 走进【zhhll.icu】技术博客
    在浩瀚无垠的编程世界里,Java以其强大的跨平台能力、丰富的生态系统和广泛的应用场景,成为了众多开发者心中的“语言之星”。而对于每一位热爱Java、渴望在编程道路上不断前行的你来说,一个能够深入探索、持续学习、并与同行交流的平台显得尤为重要。今天,就让我带你走进这样一......
  • CEC2017(Python):七种算法(PSO、RFO、DBO、HHO、SSA、DE、GWO)求解CEC2017
    一、7种算法简介1、粒子群优化算法PSO2、红狐优化算法RFO3、蜣螂优化算法DBO4、哈里斯鹰优化算法HHO5、麻雀搜索算法SSA6、差分进化算法DE7、灰狼优化算法GWO二、CEC2017简介参考文献:[1]Awad,N.H.,Ali,M.Z.,Liang,J.J.,Qu,B.Y.,&Suganthan,P.N.(2......
  • CEC2017(Python):七种算法(RFO、DBO、HHO、SSA、DE、GWO、OOA)求解CEC2017
    一、7种算法简介1、红狐优化算法RFO2、蜣螂优化算法DBO3、哈里斯鹰优化算法HHO4、麻雀搜索算法SSA5、差分进化算法DE6、灰狼优化算法GWO7、鱼鹰优化算法OOA二、CEC2017简介参考文献:[1]Awad,N.H.,Ali,M.Z.,Liang,J.J.,Qu,B.Y.,&Suganthan,P.N.(201......
  • 【一百一十】【算法分析与设计】[SDOI2009] HH的项链,树状数组应用,查询区间的种类数,
    P1972[SDOI2009]HH的项链[SDOI2009]HH的项链题目描述HH有一串由各种漂亮的贝壳组成的项链。HH相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH不断地收集新的贝壳,因此,他的项链变得越来越长。有一天,他突然提出了一个问......
  • P2167 [SDOI2009] Bill的挑战
    P2167[SDOI2009]Bill的挑战状压dp/二项式反演先说状压,考虑怎么刻画\(S\)和\(T\)匹配这个东西。实质上就是从前往后匹配每一位,直到哪一位不匹配了,那么就不匹配,也就是每一位字符匹配的并集。同样,对于多个串的匹配,设第\(i\)位字符为\(j\)时匹配的串集合为\(g_{i,j}\),对......