博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
树状数组及其他特别简单的扩展
阅读量:5833 次
发布时间:2019-06-18

本文共 3053 字,大约阅读时间需要 10 分钟。

度娘真是个好东西

struct node{    int len;    int tree[1000100];    int lowbit(int x)    {        return x&(-x);    }    void updata(int x,int value)    {        while(x<=len)        {            tree[x]+=value;            x+=lowbit(x);        }    }    int sum(int x)    {        int ans=0;        while(x>0)        {            ans+=tree[x];            x-=lowbit(x);        }        return ans;    }    int check(int x,int y)    {        return sum(y)-sum(x-1);    } };

树状数组可以快速的查询区间和插叙两次

所以我们就可以将被求和换成其他意义的数组,完成不同的任务

比如说区间修改和单点查询(注意这两个是同时存在的),还比如求逆序对

上题

对于逆序对这道题,在桶拍上用树状数组,还需要进行离散化。如果数据范围是int以外,那直接开桶是要炸的 树状数组就是个辣鸡

#include
#include
using namespace std;struct haha{ int val; int hao;};bool compare(haha a,haha b){ return a.val>b.val;}haha in[41000];struct node{ int tree[41000]; int num; int lowbit(int x) { return x&(-x); } void updata(int i,int value) { while(i<=num) { tree[i]+=value; i+=lowbit(i); } return ; } int sum(int x) { int ans=0; if(x) while(x>0) { ans+=tree[x]; x-=lowbit(x); } return ans; } int check(int x,int y) { return sum(y)-sum(x-1); }};node bit;int cym[41000],da=0,h=0;int main(){ cin.sync_with_stdio(false);//没错,我就是懒 /*freopen("testdata.in","r",stdin); freopen("testdata.out","w",stdout);*/ int n; cin>>n; bit.num=n; int ans=0; for(int i=1;i<=n;i++) { cin>>in[i].val; in[i].hao=i; } sort(in+1,in+n+1,compare); for(int i=1;i<=n;i++) { if(h!=in[i].val) { da++;//第几大 h=in[i].val;//如果有重复的就是一样大 } cym[in[i].hao]=da; } for(int i=1;i<=n;i++)//顺序插入,为什么??就不告诉你,自己想去吧 { ans+=bit.check(0,cym[i]-1); bit.updata(cym[i],1); } cout<

区间修改和单点查询的话就是利用数组。

#include
#include
using namespace std;struct node{ int len; int tree[500100]; node(){len=0;memset(tree,0,sizeof(tree));} int lowbit(int x) { return x&(-x); } void updata(int pos,int value) { while(pos<=len) { tree[pos]+=value; pos+=lowbit(pos); } } int sum(int pos) { if(!pos) return 0; int pass=0; while(pos>0) { pass+=tree[pos]; pos-=lowbit(pos); } return pass; } int check(int left,int right) { return sum(right)-sum(left-1); }};node bit;int main(){ cin.sync_with_stdio(false); int n,m; cin>>n>>m; int a,b,c,d=0; bit.len=n; for(int i=1;i<=n;i++) { cin>>a; bit.updata(i,a-d); d=a; } for(int i=1;i<=m;i++) { cin>>a; if(a==1) { cin>>b>>c>>d; bit.updata(b,d); bit.updata(c+1,-1*d); } if(a==2) { cin>>b; cout<
<

转载于:https://www.cnblogs.com/Lance1ot/p/8494597.html

你可能感兴趣的文章
传值方式:ajax技术和普通传值方式
查看>>
Linux-网络连接-(VMware与CentOS)
查看>>
寻找链表相交节点
查看>>
AS3——禁止swf缩放
查看>>
linq 学习笔记之 Linq基本子句
查看>>
[Js]布局转换
查看>>
Hot Bath
查看>>
国内常用NTP服务器地址及
查看>>
Java annotation 自定义注释@interface的用法
查看>>
Apache Spark 章节1
查看>>
phpcms与discuz的ucenter整合
查看>>
Linux crontab定时执行任务
查看>>
mysql root密码重置
查看>>
33蛇形填数
查看>>
选择排序
查看>>
SQL Server 数据库的数据和日志空间信息
查看>>
前端基础之JavaScript
查看>>
自己动手做个智能小车(6)
查看>>
自己遇到的,曾未知道的知识点
查看>>
P1382 楼房 set用法小结
查看>>