题意:给n条要么垂直要么平行于坐标轴的宽度为1的线段,问你这些线段包含点的个数。
线段树 + 离散化+ 扫描线,确定好坐标就可以了。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <string>
#define INF 0x3f3f3f3f
#define eps 1e-8
#define MAXN (200000+10)
#define MAXM (500000)
#define Ri(a) scanf("%d", &a)
#define Rl(a) scanf("%lld", &a)
#define Rf(a) scanf("%lf", &a)
#define Rs(a) scanf("%s", a)
#define Pi(a) printf("%d\n", (a))
#define Pf(a) printf("%.2lf\n", (a))
#define Pl(a) printf("%lld\n", (a))
#define Ps(a) printf("%s\n", (a))
#define W(a) while(a--)
#define CLR(a, b) memset(a, (b), sizeof(a))
#define MOD 1000000007
#define LL long long
#define lson o<<1, l, mid
#define rson o<<1|1, mid+1, r
#define ll o<<1
#define rr o<<1|1
#define PI acos(-1.0)
using namespace std;
struct Tree
{
int l, r;
double sum;
int cover;
};
Tree tree[MAXN<<2];
struct Node
{
double x1, x2, y;
int cover;
};
Node node[MAXN];
bool cmp(Node a, Node b){
return a.y < b.y;
}
void build(int o, int l, int r)
{
tree[o].l = l, tree[o].r = r;
tree[o].sum = tree[o].cover = 0;
if(l == r)
return ;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
double rec[MAXN];
void PushUp(int o)
{
if(tree[o].cover)
tree[o].sum = rec[tree[o].r+1] - rec[tree[o].l];
else
{
if(tree[o].l == tree[o].r)
tree[o].sum = 0;
else
tree[o].sum = tree[ll].sum + tree[rr].sum;
}
}
void update(int L, int R, int o, int v)
{
if(L <= tree[o].l && R >= tree[o].r)
{
tree[o].cover += v;
PushUp(o);
return ;
}
int mid = (tree[o].l + tree[o].r) >> 1;
if(R <= mid)
update(L, R, ll, v);
else if(L > mid)
update(L, R, rr, v);
else
{
update(L, mid, ll, v);
update(mid+1, R, rr, v);
}
PushUp(o);
}
int Find(int l, int r, double val)
{
while(r >= l)
{
int mid = (l + r) >> 1;
if(rec[mid] == val)
return mid;
else if(rec[mid] > val)
r = mid - 1;
else
l = mid + 1;
}
return -1;
}
int main()
{
int n; Ri(n);
int k = 1;
double x1, y1, x2, y2;
for(int i = 0; i < n; i++)
{
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
if(x1 == x2)
{
if(y1 > y2)
swap(y1, y2);
}
if(y1 == y2)
{
if(x1 > x2)
swap(x1, x2);
}
x2++; y2++;
node[k].x1 = x1; node[k].x2 = x2;
node[k].y = y1; node[k].cover = 1;
rec[k++] = x1;
node[k].x1 = x1; node[k].x2 = x2;
node[k].y = y2; node[k].cover = -1;
rec[k++] = x2;
}
sort(node+1, node+k, cmp);
sort(rec+1, rec+k);
int R = 2;
for(int i = 2; i < k; i++)
if(rec[i] != rec[i-1])
rec[R++] = rec[i];
sort(rec+1, rec+R);
build(1, 1, R-1);
double ans = 0;
for(int i = 1; i < k-1; i++)
{
int x = Find(1, R-1, node[i].x1);
int y = Find(1, R-1, node[i].x2);
if(x <= y-1) update(x, y-1, 1, node[i].cover);
ans += tree[1].sum * (node[i+1].y - node[i].y);
}
printf("%.0lf\n", ans);
return 0;
}