AtCoder Beginner Contest 106 D - AtCoder Express 2(二维树状数组)

题目大意:从西到东有N个城市,其中有M条铁路路线,每条铁路路线链接Ni-Nj(j>=i),有Q次询问,询问Ni到Nj完全包含的铁路数量。

举个例子,比如总共有三个站点,1,2,3四个路线,(1,1),(1,2),(1,3),(2,2)查询(1,2)之间完全包含的铁路数量,答案是3个( (1,1),(1,2),(2,2))。

这道题可以使用动态规划,二维树状数组或者二分查找。效率最高的是动态规划,其次二维树状数组,再二分查找,这里我讲一下二维树状数组的写法。

因为题目要我们求一个区间内的路线的数量,我们可以把区间的左右当做坐标轴上的x,y然后画一个图,不难看出我们要求的是一个点(x,y)其左下角的点,那我们可以写一个二维数组,每次更新的时候x往前更新,y往后更新,为什么是x是往前更新呢,你想一下,(2,5)这个区间,应该被(2,5),(1,5)包含,而不是(3,5),(4.5)所以应该往前更新(这个大概是我独特的思维方式,你们感受一下就好了)。查询的时候反一下就好了。

下面是代码:

#include <iostream>
#include<algorithm>
using namespace std;
int d[551][551];
int n,m,q;
void updata(int x,int y)
{
	int t;
	while(x>0)
	{
		t=y;
		while(t<=n)
		{
			d[x][t]++;
			t+=t&-t;
		}
		x-=x&-x;
	}
}
int que(int x,int y)
{
	int sum=0;
	int t;
	while(x<=n)
	{
		t=y;
		while(t>0)
		{
			sum+=d[x][t];
			t-=t&-t;
		}
		x+=x&-x;
	}
	return sum;
}
int main(int argc, char *argv[])
{
	cin>>n>>m>>q;
	int a,b;
	for(int i=1;i<=m;i++)
	{
		cin>>a>>b;
		updata(a,b);
	}
	for(int i=0;i<q;i++)
	{
		cin>>a>>b;
		cout<<que(a,b)<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36715504/article/details/81835808