题意:就是东边有n个城市,西边有m个城市,有k条直线公路连接东西两边的城市,问这些公路有多少个交点。
之前做了奶牛那题,做这题也算是有思路,瞎搞一下就好了,不过。。忘记初始化。。改了一个多小时也是够够的了。。。好像也可以用二维树状数组做。。反正我不会。。
思路:先把公路按东边的城市从大到小排序,如果东边的城市相同则西边的城市也从大到小排序,这样就可以不用去重的那一步啦,然后就是常规树状数组操作了。这题数据大要用long long int 不然又是好几发WA。
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1000005;
ll sum[1100], n, m;
struct Node{
ll l, r;
}node[maxn];
bool cmp(Node a,Node b){
if(a.l == b.l)
return a.r > b.r;
return a.l > b.l;
}
ll lowbit(ll x){
return x&(-x);
}
void add(ll x){
for(int i = x; i <= m; i+=lowbit(i))
sum[i]++;
}
ll query(ll x){
ll ans = 0;
for(ll i = x; i > 0; i-=lowbit(i))
ans += sum[i];
return ans;
}
int main(){
ll T, k;
scanf("%lld",&T);
for(ll Case = 1; Case <= T; Case++){
memset(sum, 0, sizeof(sum));
scanf("%lld%lld%lld",&n,&m,&k);
for(int i = 1; i <= k; i++)
scanf("%lld%lld",&node[i].l,&node[i].r);
sort(node+1, node+1+k, cmp);
ll ans = 0;
for(ll i = 1; i <= k; i++){
ans += query(node[i].r-1);
add(node[i].r);
}
printf("Test case %lld: %lld\n",Case,ans);
}
return 0;
}