传送门:QAQ
题意:给你一个矩形,给你几条线,问你矩形被分成了多少区域。
思路:离散化一下后,就是经典的树状数组求逆序数,离散化真好,注意会爆(int)。
附上代码:
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
struct inst {
int x;
int y;
};
int srt[110000];
int cx[1100000];
inst ax[110000];
const int maxn = 110000;
int n;
long long c[maxn], a[maxn];
int lowbit(int x)
{
return (x)&(-x);
}
void update_onepos(int pos, int x)
{
while (pos <= maxn)
{
c[pos] += x;
pos += lowbit(pos);
}
}
long long getsum_onepos(int pos)
{
long long sum = 0;
while (pos > 0)
{
sum += c[pos];
pos -= lowbit(pos);
}
return sum;
}
void build()
{
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++)
{
update_onepos(i, a[i]);
}
}
int cmp(inst a, inst b) {
return a.x < b.x;
}
int main(void) {
int n, m;
scanf("%d%d", &n, &m);
int a, b;
scanf("%d%d", &a, &b);
for (int i = 0; i < a; i++) {
scanf("%d%d", &ax[i].x, &ax[i].y);
srt[i] = ax[i].y;
}
build();
sort(srt, srt + a);
sort(ax, ax + a, cmp);
for (int i = 0; i < a; i++) {
cx[i] = lower_bound(srt, srt + a, ax[i].y) - srt;
}
long long sum = 0;
for (int i = 0; i < a; i++) {
update_onepos(cx[i]+1,1);
sum += (i+1 - getsum_onepos(cx[i]+1));
}
for (int i = 0; i < b; i++) {
scanf("%d%d", &ax[i].x, &ax[i].y);
srt[i] = ax[i].y;
}
sort(srt, srt + b);
sort(ax, ax + b, cmp);
build();
for (int i = 0; i < b; i++) {
cx[i] = lower_bound(srt, srt + b, ax[i].y) - srt;
}
for (int i = 0; i < b; i++) {
update_onepos(cx[i]+1, 1);
sum += (i+1 - getsum_onepos(cx[i]+1));
}
printf("%lld\n", sum + (long long)a*(long long)b + a + b + 1);
return 0;
}