模板题:https://www.luogu.org/problem/P5490 与 http://poj.org/problem?id=1151
扫描线从左向右扫,rwa[]数组表示整数值 i 对应的原始 y 坐标值。 c[i] 记录扫描线上第 i 段覆盖的次数,ans 每次累加上 len*(x2-x1)即可 ,朴素做法O(n^2) ,用线段树维护 c 数组后复杂度 O(n*longn)
//#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
const ll maxn = 1e6+100;
ll n,num,c[maxn];
ll x1[maxn],x2[maxn],y1[maxn],y2[maxn],raw[maxn];
struct sgt
{
ll l,r,cnt;
ll len;
}tree[maxn<<2];
struct node
{
ll x,y1,y2;
ll k;
ll valy1,valy2;
}arr[maxn*2];
bool cmp(node a,node b)
{
return a.x < b.x;
}
void build(ll now,ll l,ll r)
{
tree[now].cnt = tree[now].len = 0;
tree[now].l = l,tree[now].r = r;
if(l == r)
return ;
ll mid = (l+r)/2;
build(now*2,l,mid);
build(now*2+1,mid+1,r);
return ;
}
void push(sgt &now,sgt <,sgt &rt)
{
if(now.cnt > 0)
now.len = raw[now.r+1] - raw[now.l];
else
now.len = lt.len + rt.len;
return ;
}
void add(ll now,ll l,ll r,ll val)
{
if(l <= tree[now].l && r >= tree[now].r)
{
tree[now].cnt += val;
push(tree[now],tree[now*2],tree[now*2+1]);
return ;
}
ll mid = (tree[now].l + tree[now].r)/2;
if(l <= mid)
add(now*2,l,r,val);
if(r >= mid+1)
add(now*2+1,l,r,val);
push(tree[now],tree[now*2],tree[now*2+1]);
return ;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
while(cin >> n && n)
{
ll ans = 0;
for(ll i = 1; i < maxn; i++)
{
c[i] = 0;
raw[i] = 0;
}
ll len = 0;
vector<ll>ty;
for(ll i = 1; i <= n; i++)
{
cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
ty.push_back(y1[i]);
ty.push_back(y2[i]);
arr[++len].k = 1;
arr[len].x = x1[i];
arr[len].y1 = y1[i];
arr[len].y2 = y2[i];
arr[++len].k = -1;
arr[len].x = x2[i];
arr[len].y1 = y1[i];
arr[len].y2 = y2[i];
}
sort(ty.begin(),ty.end());
ty.erase(unique(ty.begin(),ty.end()),ty.end());
sort(arr+1,arr+1+len,cmp);
for(ll i = 1; i <= len; i++)
{
arr[i].valy1 = lower_bound(ty.begin(),ty.end(),arr[i].y1) - ty.begin()+1;
arr[i].valy2 = lower_bound(ty.begin(),ty.end(),arr[i].y2) - ty.begin()+1;
raw[ arr[i].valy1 ] = arr[i].y1;
raw[ arr[i].valy2 ] = arr[i].y2;
}
build(1,1,ty.size()-1);
for(ll i = 1; i <= len; i++)
{
if(i > 1)
ans += (arr[i].x-arr[i-1].x)*tree[1].len;
ll low = arr[i].valy1,high = arr[i].valy2-1;
add(1,low,high,arr[i].k);
}
num++;
cout << ans << endl;
}
return 0;
}
O(n^2)代码
//#include <bits/stdc++.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#define endl '\n'
using namespace std;
typedef long long ll;
typedef long double ld;
const ll maxn = 1e5+100;
ll n,num,c[maxn];
ld x1[maxn],x2[maxn],y1[maxn],y2[maxn],raw[maxn];
struct node
{
ld x,y1,y2;
ll k;
ll valy1,valy2;
}arr[maxn*2];
bool cmp(node a,node b)
{
return a.x < b.x;
}
int main()
{
//ios::sync_with_stdio(false);
//cin.tie(0),cout.tie(0);
while(cin >> n && n)
{
ld ans = 0;
for(ll i = 1; i < maxn; i++)
{
c[i] = 0;
raw[i] = 0;
}
ll len = 0;
vector<ld>ty;
for(ll i = 1; i <= n; i++)
{
cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];
ty.push_back(y1[i]);
ty.push_back(y2[i]);
arr[++len].k = 1;
arr[len].x = x1[i];
arr[len].y1 = y1[i];
arr[len].y2 = y2[i];
arr[++len].k = -1;
arr[len].x = x2[i];
arr[len].y1 = y1[i];
arr[len].y2 = y2[i];
}
sort(ty.begin(),ty.end());
ty.erase(unique(ty.begin(),ty.end()),ty.end());
sort(arr+1,arr+1+len,cmp);
for(ll i = 1; i <= len; i++)
{
arr[i].valy1 = lower_bound(ty.begin(),ty.end(),arr[i].y1) - ty.begin()+1;
arr[i].valy2 = lower_bound(ty.begin(),ty.end(),arr[i].y2) - ty.begin()+1;
raw[ arr[i].valy1 ] = arr[i].y1;
raw[ arr[i].valy2 ] = arr[i].y2;
}
for(ll i = 1; i <= len; i++)
{
if(i > 1)
{
ld h = 0;
for(ll j = 1; j < ty.size(); j++)
{
if(c[j] > 0)
h += (raw[j+1]-raw[j]);
}
ans += (arr[i].x - arr[i-1].x)*h;
//cout << "答案 " << h << " " << ans << endl;
}
ll low = arr[i].valy1,high = arr[i].valy2-1;
for(ll j = low; j <= high; j++)
{
c[j] += arr[i].k;
}
}
num++;
cout << "Test case #" << num << endl;
cout << "Total explored area: " << fixed << setprecision(2) << ans << endl;
cout << endl;
}
return 0;
}