多数人使用了树状数组,这道题目其实还可以暴力打表,题意就是日本东边有N个城市,西边有M个,左右之间需要高速公路连起来,连接题目已经给出,问高速公路的交点个数,题目已经声明 三条及三条以上的高速路 绝对不会相交于同一点
打表举个例子:
1,2,3,4表示东边城市标号,1,2,3,4,5,表示西边的,如果题目给出东边3与西边3相连,下面表中的 ** 号表示已经连接,那么影响高速交点 个数的 连接 就是下面表中的 # 部分,随便一个草图一画,就能够轻易找到规律,这样多对已知连接出现时,其实是有一个包含叠加的关系,所以直接暴力打表就可以了
我是使用了线段树,乱搞搞出来的,自己也是WA了很多次,最后迷迷糊糊的 写出来了,也是利用了 画草图 ,多画画就有思路了
#include<iostream>
#include<cstdio>
#include<list>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<cmath>
#include<memory.h>
#include<set>
#define ll long long
#define eps 1e-7
#define inf 0xfffffff
const ll INF = 1ll<<61;
using namespace std;
//vector<pair<int,int> > G;
//typedef pair<int,int > P;
//vector<pair<int,int> > ::iterator iter;
//
//map<ll,int >mp;
//map<ll,int >::iterator p;
//
typedef struct {
int l;
int r;
int w;
}Node;
Node tree[1000000 + 5];
struct node {
int x;
int y;
}p[1000000 + 5];
void clear() {
memset(tree,0,sizeof(tree));
memset(p,0,sizeof(p));
}
bool cmp(node x,node y) {
if(x.x == y.x)
return x.y>y.y;
return x.x>y.x;
}
void build(int root,int left,int right) {
tree[root].l = left;
tree[root].r = right;
if(tree[root].l == tree[root].r - 1)
return ;
int mid = (left + right)/2;
build(root * 2,left,mid);
build(root * 2 + 1,mid,right);
}
int find(int root,int left,int right) {
if(tree[root].l >= left && tree[root].r <=right)
return tree[root].w;
if(tree[root].l == tree[root].r - 1)
return 0;
int ans = 0;
int mid = (tree[root].l + tree[root].r)/2;
if(left <= mid)
ans += find(root * 2,left,right);
if(right > mid)
ans += find(root * 2 + 1,left,right);
return ans;
}
void update(int root,int left,int right) {
if(tree[root].l >= left && tree[root].r <= right) {
tree[root].w++;
return;
}
if(tree[root].l == tree[root].r - 1)
return;
int mid =(tree[root].l + tree[root].r)/2;
if(left <= mid)
update(root *2,left,right);
if(right > mid)
update(root * 2 + 1,left,right);
tree[root].w = tree[root * 2 + 1].w + tree[root * 2].w;
}
int main() {
int Case = 0;
ll ans;
int n,m,k,t;
scanf("%d",&t);
while(t--) {
clear();
ans = 0;
scanf("%d %d %d",&n,&m,&k);
int maxn = max(n,m);
for(int i=0;i<k;i++)
scanf("%d %d",&p[i].x,&p[i].y);
sort(p,p+k,cmp);
build(1,1,maxn);
for(int i=0;i<k;i++) {
ans += find(1,1,p[i].y);
update(1,p[i].y,p[i].y + 1);
}
printf("Test case %d: %I64d\n",++Case,ans);
}
return EXIT_SUCCESS;
}