树状数组及其他特别简单的扩展

度娘真是个好东西

树状数组


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<iostream>
#include<algorithm>
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<<ans;
}

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

#include<iostream>
#include<cstring>
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<<bit.check(1,b)<<endl;
		}
	}
}
posted @ 2018-03-02 18:21  Lance1ot  阅读(144)  评论(0编辑  收藏  举报