首页 > 其他分享 >树状数组

树状数组

时间:2024-02-18 17:56:37浏览次数:31  
标签:遍历 树状 int 离线 更新 计算结果 数组

HH的项链

看到这题,我首先想到了用flag[]数组标记,很明显这是必需的。
但随着代码进行,又会遇到一个问题:如1 2 1 2,如果按照正常标记后面两个就不会被标记,那遍历3到4时,结果为0。
顺着思路想,如果我们在用完一次后把它丢掉,重新遍历,这也就导致我们必须要采用一种有序遍历,从而让后面的更新不会影响前面的结果,同时,我们也要每次更新完数据,自动计算结果并保存,后面更新就不再计算(离线)。到这,这道题的大体思路明了。

这里了解到几个新东西。
离线
在第一次更新到这个状态时,计算结果,即使后面再更新数据,也不再改变结果。
在线
每次数据更新,重新计算结果。

接下来就是代码了

点击查看代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+6;
struct lmy//多个变量排序时可控 
{
    int l,r;
    int id;
    bool operator <(const lmy a)
	{
        return r<a.r;//以右边界大小排序
		//遍历完后处理的数据不受影响 
    }
}q[N];
int a[N];
int mark[N];//mark[i]表示i上一次出现的位置
int c[N];
int ans[N];//保存结果
int n,m;
int lowbit(int x)
{
	return x&-x;
}
void add(int x,int t)
{
    while(x<=n)
	{
        c[x]+=t;
        x+=lowbit(x);
    }
}

int getsum(int x)
{
    int ans=0;
    while(x)
	{
        ans+=c[x];
        x-=lowbit(x);
    }
    return ans;
}


int main()
{
    ios::sync_with_stdio(0);
    cin>>n;
    for(int i=1;i<=n;i++)
	{
        cin>>a[i];
    }
    cin>>m;
    for(int i=1;i<=m;i++)
	{
        cin>>q[i].l>>q[i].r;
        q[i].id=i;
    }
    sort(q+1,q+1+m);
    int last=1;//上次查询的结尾+1
    for(int i=1;i<=m;i++)
	{
        for(int j=last;j<=q[i].r;j++)
		{
            if(mark[a[j]])
			//如果为0,它为第一个数 
			//不为0,则有上一个数 
			{
                add(mark[a[j]],-1);//上一个数置0 
            }
            add(j,1);
            mark[a[j]]=j;//标记为上一个数 
        }
        last=q[i].r+1;
        ans[q[i].id]=getsum(q[i].r)-getsum(q[i].l-1);
    }
    for(int i=1;i<=m;i++)
	{
        cout<<ans[i]<<endl;
    }
    return 0;
}

标签:遍历,树状,int,离线,更新,计算结果,数组
From: https://www.cnblogs.com/zhengchenxi/p/18019670

相关文章

  • 请编写函数fun,它的功能是:求出1到100之内能被7或者11整除, 但不能同时被7和11整除的所有
    /2.请编写函数fun,它的功能是:求出1到100之内能被7或者11整除,但不能同时被7和11整除的所有整数,并将他们放在a所指的数组中,通过n返回这些数的个数/#include<stdio.h>#include<string.h>intfun(int*buf){inti=1,j=0;for(i=1;i<100;i++){if(i%7==......
  • 1.m个人的成绩存放在score数组中,请编写函数fun, 它的功能是:将低于平均分的人数作为函
    /1.m个人的成绩存放在score数组中,请编写函数fun,它的功能是:将低于平均分的人数作为函数值返回,将低于平均分的分数放在below所指1定的数组中。/#include<stdio.h>#include<string.h>intfun(int*buf,int*buff,intnum){inti=0,j=0,sum=0;for(i=......
  • 1.1 - numpy数组的属性和创建
    1.1.1numpy数组Numpy(NumberPython)是Python进行科学计算的一个扩展库,提供了大量的函数和操作,主要用于对多维数组执行计算。Numpy数组中的每个元素都有相同的类型;并且数组大小是不可变的,修改数组大小将会创建新的数组。而python的列表类型list则会动态的扩展长度。1.1.......
  • 树状数组
    从这边抄(借鉴)的这是一个完整的二叉树把它变成直角三角形下面用一维数组对应删掉多余的叶子这个就是树状数组......
  • 数据结构【树状数组】
    树状数组是线段树的衍生产物,牺牲了部分通用性,节约了空间,且大大减少了手写码量。借助树状数组,我们可以用O(logN)的时间复杂度来实现给定序列中长度为n的区间中元素和的计算。https://www.bilibili.com/video/BV1ce411u7qP/?spm_id_from=333.337.search-card.all.click&vd_source......
  • 字符串、向量和数组
    一、字符串1.引入库include<string>usingstd::string;2.初始化strings(10,'c');//直接初始化strings1("hello");//直接初始化strings2="hello";//拷贝初始化3.操作(1)s+="world"//左值引用(返回值),避免拷贝(2)st......
  • 树状DP心得
    说一下近日所学的主要两种题型,一个是分叉情况问题,一种是树上背包问题。分叉情况问题具体的题可以参考小胖守皇宫和三色二叉树。点击查看代码小胖守皇宫#include<bits/stdc++.h>usingnamespacestd;constintN=2000;vector<int>son[N];intfa[N],h[N],f[N][3];//f[0]......
  • 2024-02-17-物联网C语言(2-数组)
    2.数组2.1数组的概念​ 数组是若干个相同类型的变量在内存中的有序存储集合。数组存储一组数据数组里面存储的数据类型必须是相同的数字在内存中会开辟一块连续的空间//定义了一个整型的数组a,a是数组的名字,数组中有10个元素,每个元素的类型都是int类型,而且在内存中连续......
  • 树状数组
    树状数组背景由于\(OIer\)们对于数据更高效的储存、修改和查询的需要,一种数据结构树状数组营运而生。介绍树状数组是一个查询和修改时间复杂度都为\(O(log(n))\)的数据结构,主要用于:数组的单点修改和区间查询在使用前缀和求区间和的算法中:如果可以做到在\(O(1)\)......
  • 树状数组-三色二叉树 题解
    题目在这里————————————————————————————————三色二叉树首先题面写的很清楚了是一道树状数组题因为这题的输入方式很特别按二叉树序列所以在输入上要特殊处理如下voidread(intx){//读入+存图以左右子树为形式如l[x]=y即y为x左子树......