题目大意:从西到东有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;
}