核心算法:一维树状数组
大意:Japan在东边有n座城市,从北到南编号依次为1,2,3...n
在西边有m座城市,从北到南编号分别为1,2,3...m
现要在南北城市之间修建k条超级高速公路,求会出现多少个十字路口
(注:每个十字路口只能由两条交叉的路所构成)
输入:T .....cases数
n,m,k
以下k行每行对应于一条高速公路,由两个数字(xi,yi)组成,xi对应于东城编号,yi西城编号
输出:十字路口数目
分析:
1.对该数组先按y从大到小排序,若y相等,则按x从大到小排序
2.从前往后扫描各条高速公路,对路(xi,yi)其与前面点的交点数目为其左上角路的个数,即所有的(xj,yj),其中xj<xi,yj>yi.
3.与poj 2352类似地,用数组数组c[i]存储x轴的信息
#include
<
stdio.h
>
#include < string .h >
#include < algorithm >
using namespace std;
const int N = 1001 ;
const int K = 1000010 ;
__int64 c[N];
int n,m,k;
struct node
{
int x,y;
bool operator < ( const node & A){ // 先按y从大到小排序,若y相同,按x从小到大排序
if (y == A.y) return x > A.x;
return y >= A.y;
}
}point[K];
inline int lowbit( int x)
{
return x & ( - x);
}
void modify( int x, int add)
{
while (x <= n)
{
c[x] += add;
x += lowbit(x);
}
}
__int64 sum( int x)
{
__int64 ans = 0 ;
while (x > 0 )
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int T;
while (scanf( " %d " , & T) != EOF)
{
int cases;
for (cases = 1 ;cases <= T;cases ++ )
{
memset(c, 0 , sizeof (c));
scanf( " %d%d%d " , & n, & m, & k);
int i;
__int64 pnum = 0 ; // 点个数
for (i = 0 ;i < k;i ++ )
{
int xx,yy;
scanf( " %d%d " , & xx, & yy);
{
point[pnum].x = xx;
point[pnum].y = yy;
pnum ++ ;
}
}
sort(point,point + pnum); // 对其排序
__int64 ans = 0 ;
for (i = 0 ;i < pnum;i ++ )
{
modify(point[i].x, 1 );
ans += sum(point[i].x - 1 );
}
printf( " Test case %d: %I64d\n " ,cases,ans);
}
}
return 0 ;
}
#include < string .h >
#include < algorithm >
using namespace std;
const int N = 1001 ;
const int K = 1000010 ;
__int64 c[N];
int n,m,k;
struct node
{
int x,y;
bool operator < ( const node & A){ // 先按y从大到小排序,若y相同,按x从小到大排序
if (y == A.y) return x > A.x;
return y >= A.y;
}
}point[K];
inline int lowbit( int x)
{
return x & ( - x);
}
void modify( int x, int add)
{
while (x <= n)
{
c[x] += add;
x += lowbit(x);
}
}
__int64 sum( int x)
{
__int64 ans = 0 ;
while (x > 0 )
{
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int T;
while (scanf( " %d " , & T) != EOF)
{
int cases;
for (cases = 1 ;cases <= T;cases ++ )
{
memset(c, 0 , sizeof (c));
scanf( " %d%d%d " , & n, & m, & k);
int i;
__int64 pnum = 0 ; // 点个数
for (i = 0 ;i < k;i ++ )
{
int xx,yy;
scanf( " %d%d " , & xx, & yy);
{
point[pnum].x = xx;
point[pnum].y = yy;
pnum ++ ;
}
}
sort(point,point + pnum); // 对其排序
__int64 ans = 0 ;
for (i = 0 ;i < pnum;i ++ )
{
modify(point[i].x, 1 );
ans += sum(point[i].x - 1 );
}
printf( " Test case %d: %I64d\n " ,cases,ans);
}
}
return 0 ;
}