区间元素种类(HH的项链)

本文介绍了一种使用线段树解决区间去重问题的算法,通过将所有区间按右端点排序并扫描,更新线段树以记录每个元素的最新位置,查询指定区间内的元素种类。核心思想是在去重时保留最右侧元素,线段树节点直接存储元素种类。

HH的项链

  1. 将所有区间读入,按右端从小到大排序。
  2. 从左至右扫描,当前元素上一次出现的位置对应线段树中的结点值全部减一,更新当前元素此次出现的位置(确保相同元素在树上只存在当前最右的一个),查询所有区间右端为当前位置的区间,求出这些区间内的元素种类。
  3. 按输入顺序输出。

核心思想:去重时保留最右的,线段树结点直接存储元素种类。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int lace[1000010],ans[1000010],last[1000010],tree[4000010],maxn=1000010;
struct node
{
    int l,r,i;
    bool operator<(const node &jkl)const
    {
        if(r!=jkl.r)
            return r<jkl.r;
            return l<jkl.l;
    }
}q[1000010];
void del(int l,int r,int now,int p)
{
    if(l==r)
    {
    tree[now]--;
    return;
    }
    int mid=(l+r)>>1;
    if(p<=mid)
        del(l,mid,now<<1,p);
    else
        del(mid+1,r,now<<1|1,p);
    tree[now]=tree[now<<1]+tree[now<<1|1];
}
void add(int l,int r,int now,int p)
{
    if(l==r)
    {
    tree[now]++;
    return;
    }
    int mid=(l+r)>>1;
    if(p<=mid)
        add(l,mid,now<<1,p);
    else
        add(mid+1,r,now<<1|1,p);
    tree[now]=tree[now<<1]+tree[now<<1|1];
}
int query(int l,int r,int now,int x,int y)
{
    if(x<=l&&r<=y)
        return tree[now];
    int mid=(l+r)>>1;
    if(y<=mid)
        return query(l,mid,now<<1,x,y);
    else if(x>mid)
        return query(mid+1,r,now<<1|1,x,y);
    else
        return query(l,mid,now<<1,x,mid)+query(mid+1,r,now<<1|1,mid+1,y);
}
int main()
{
    //freopen("1.txt","r",stdin);
    int n,m;
    cin>>n;
    for(int i=1;i<=n;++i)
    {
        scanf("%d",&lace[i]);
        lace[i]++;
    }
    cin>>m;
    for(int i=1;i<=m;++i)
    {
        scanf("%d%d",&q[i].l,&q[i].r);
        q[i].i=i;
    }
    sort(q+1,q+m+1);
    int con=1;
    for(int i=1;i<=n;++i)
    {
    if(last[lace[i]])
        del(1,maxn,1,last[lace[i]]);
    last[lace[i]]=i;
    add(1,maxn,1,i);
    while(q[con].r==i)
    {
        ans[q[con].i]=query(1,maxn,1,q[con].l,i);
        con++;
    }
    }
    for(int i=1;i<=m;++i)
        printf("%d\n",ans[i]);
    return 0;
}

 

# P1972 [SDOI2009] HH项链 ## 题目描述 HH 有一串由各种漂亮的贝壳组成的项链HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。 有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。 ## 输入格式 一行一个正整数 $n$,表示项链长度。 第二行 $n$ 个正整数 $a_i$,表示项链中第 $i$ 个贝壳的种类。 第三行一个整数 $m$,表示 HH 询问的个数。 接下来 $m$ 行,每行两个整数 $l,r$,表示询问的区间。 ## 输出格式 输出 $m$ 行,每行一个整数,依次表示询问对应的答案。 ## 输入输出样例 #1 ### 输入 #1 ``` 6 1 2 3 4 3 5 3 1 2 3 5 2 6 ``` ### 输出 #1 ``` 2 2 4 ``` ## 说明/提示 【数据范围】 对于 $20\%$ 的数据,$1\le n,m\leq 5000$; 对于 $40\%$ 的数据,$1\le n,m\leq 10^5$; 对于 $60\%$ 的数据,$1\le n,m\leq 5\times 10^5$; 对于 $100\%$ 的数据,$1\le n,m,a_i \leq 10^6$,$1\le l \le r \le n$。 本题可能需要较快的读入方式,最大数据点读入数据约 20MB#include <bits/stdc++.h> #define p pair<int,int> #define lowbit(x) x&-x using namespace std; const int N = 1e6+5, M = 1e6+5; int n, m, now = 1;//now为查询双指针 int tree[N], ans[M];//树状数组、答案数组 p arr[N];//元素存储数组,[value,pos] void update(int pos) {//自pos往后加一 for (; pos <= n; pos += lowbit(pos)) tree[pos]++; } int query(int pos) {//自pos往前累加 int res = 0; for (; pos >= 1; pos -= lowbit(pos)) res += tree[pos]; return res; } struct qs { int L, R, X, pos;//左右区间,查询值,查询顺序 } q[M]; int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> arr[i].first; arr[i].second = i; } sort(arr + 1, arr + 1 + n, [](const p & a, const p & b) {//按值降序 return a.first > b.first; }); for (int i = 1; i <= m; i++) { cin >> q[i].L >> q[i].R >> q[i].X; q[i].pos = i; } sort(q + 1, q + 1 + m, [](const qs & a, const qs & b) {//按值降序 return a.X > b.X; }); for (int i = 1; i <= m; i++) { while (arr[now].first >= q[i].X && now <= n) {//now.value>=query.x则更新 update(arr[now].second); now++; } ans[q[i].pos] = query(q[i].R) - query(q[i].L - 1);//区间查询 } for (int i = 1; i <= m; i++)//输出答案 cout << ans[i] << '\n'; return 0; } 之前的题目我已经用上面这个代码通过了,我想要知道,离线树状数组如何处理种类查询问题
08-17
内容概要:本文介绍了一个基于Matlab的综合能源系统优化调度仿真资源,重点实现了含光热电站、有机朗肯循环(ORC)和电含光热电站、有机有机朗肯循环、P2G的综合能源优化调度(Matlab代码实现)转气(P2G)技术的冷、热、电多能互补系统的优化调度模型。该模型充分考虑多种能源形式的协同转换与利用,通过Matlab代码构建系统架构、设定约束条件并求解优化目标,旨在提升综合能源系统的运行效率与经济性,同时兼顾灵活性供需不确定性下的储能优化配置问题。文中还提到了相关仿真技术支持,如YALMIP工具包的应用,适用于复杂能源系统的建模与求解。; 适合人群:具备一定Matlab编程基础和能源系统背景知识的科研人员、研究生及工程技术人员,尤其适合从事综合能源系统、可再生能源利用、电力系统优化等方向的研究者。; 使用场景及目标:①研究含光热、ORC和P2G的多能系统协调调度机制;②开展考虑不确定性的储能优化配置与经济调度仿真;③学习Matlab在能源系统优化中的建模与求解方法,复现高水平论文(如EI期刊)中的算法案例。; 阅读建议:建议读者结合文档提供的网盘资源,下载完整代码和案例文件,按照目录顺序逐步学习,重点关注模型构建逻辑、约束设置与求解器调用方式,并通过修改参数进行仿真实验,加深对综合能源系统优化调度的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值