【線段樹+掃描線】&矩形覆蓋求面積/周長問題(POJ
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf 0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 5005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=1e9+7;
double sum[N],a[N];
int f[N];
struct node
{
double lx,rx,y;
int flag;
node(){}
node(double a,double b,double c,double d)
{
lx=a,rx=b,y=c,flag=d;
}
bool operator<(const node b) const
{
return y<b.y;
}
}line[N];
int findx(double x,int n)
{
return lower_bound(a+1,a+1+n,x)-a;
}
void push_up(int u,int l,int r)
{
if(f[u]) sum[u]=a[r+1]-a[l];
else if(l==r) sum[u]=0;
else sum[u]=sum[u<<1]+sum[u<<1|1];
}
void update(int u,int l,int r,int tl,int tr,int x)
{
if(tr<l||tl>r) return ;
if(tl<=l&&r<=tr)
{
f[u]+=x;
push_up(u,l,r);
return ;
}
int mid=(l+r)>>1;
update(u<<1,l,mid,tl,tr,x);
update(u<<1|1,mid+1,r,tl,tr,x);
push_up(u,l,r);
}
int main()
{
int n,m,t=1;
while(~sd(m)&&m)
{
int num=0;
mem(f,0);
mem(sum,0);
n=0;
fup(i,1,m)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[++n]=node(x1,x2,y1,1);
a[n]=x1;
line[++n]=node(x1,x2,y2,-1);
a[n]=x2;
};
sort(a+1,a+1+n);
sort(line+1,line+1+n);
int len=1;
for(int i=2; i<=n; i++)
if(a[i]!=a[i+1]) a[++len]=a[i];
// cout<<len<<' '<<n<<endl;
double ans=0;
fup(i,1,n-1)
{
int l=findx(line[i].lx,len);
int r=findx(line[i].rx,len)-1;
update(1,1,len,l,r,line[i].flag);
// cout<<l<<' '<<line[i].y<<endl;
ans+=sum[1]*(line[i+1].y-line[i].y);
}
printf("Test case #%d\n",t++);
printf("Total explored area: %.2lf\n\n",ans);
}
}
HDU 1828
方法1
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf 0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 50005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=1e9+7;
double a[N];
int b[N][4];
struct tre
{
int len;///這個區間被覆蓋的長度
int f;///表示這個區間被重複覆蓋了幾次
}t[N];
struct node
{
double lx,rx,y;
int flag;
node(){}
node(double a,double b,double c,double d)
{
lx=a,rx=b,y=c,flag=d;
}
bool operator<(const node b) const
{
return y<b.y;
}
}line[N];
int findx(double x,int n)
{
return lower_bound(a+1,a+1+n,x)-a;
}
void push_up(int u,int l,int r)
{
if(t[u].f) t[u].len=a[r+1]-a[l];
else if(l==r) t[u].len=0;
else t[u].len=t[u<<1].len+t[u<<1|1].len;
}
void update(int u,int l,int r,int tl,int tr,int x)
{
if(tr<l||tl>r) return ;
if(tl<=l&&r<=tr)
{
t[u].f+=x;
push_up(u,l,r);
return ;
}
int mid=(l+r)>>1;
update(u<<1,l,mid,tl,tr,x);
update(u<<1|1,mid+1,r,tl,tr,x);
push_up(u,l,r);
}
int main()
{
int n,m;
while(~sd(m)&&m)
{
double ans=0,last=0;
mem(t,0);
n=0;
fup(i,1,m)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
b[i][0]=x1,b[i][1]=y1,b[i][2]=x2,b[i][3]=y2;
line[++n]=node(x1,x2,y1,1);
a[n]=x1;
line[++n]=node(x1,x2,y2,-1);
a[n]=x2;
};
sort(a+1,a+1+n);
sort(line+1,line+1+n);
int len=1;
for(int i=2; i<=n; i++)
if(a[i]!=a[i+1]) a[++len]=a[i];
fup(i,1,n)
{
int l=findx(line[i].lx,len);
int r=findx(line[i].rx,len)-1;
update(1,1,len,l,r,line[i].flag);
ans+=fabs(t[1].len-last);
last=t[1].len;
}
///----------------------------------------
mem(t,0);
n=0;
fup(i,1,m)
{
line[++n]=node(b[i][1],b[i][3],b[i][0],1);
a[n]=b[i][1];
line[++n]=node(b[i][1],b[i][3],b[i][2],-1);
a[n]=b[i][3];
};
sort(a+1,a+1+n);
sort(line+1,line+1+n);
len=1;
for(int i=2; i<=n; i++)
if(a[i]!=a[i+1]) a[++len]=a[i];
fup(i,1,n)
{
int l=findx(line[i].lx,len);
int r=findx(line[i].rx,len)-1;
update(1,1,len,l,r,line[i].flag);
ans+=fabs(t[1].len-last);
last=t[1].len;
}
printf("%.0lf\n",ans);
}
}
方法2
#include<stdio.h>
#include<string.h>
#include<string>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<stdlib.h>
#include<time.h>
#include <iomanip>
#define lowbit(x) (x&(-x))
#define inf 0x7fffffff
#define linf 0x7fffffffffffffff
#define mem(x,y) memset(x,y,sizeof(x))
#define fup(i,x,y) for(int i=(x);i<=(y);i++)
#define fdn(i,x,y) for(int i=(x);i>=(y);i--)
#define sp(x) setprecision(x)
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define sc(n) scanf("%s",&n)
#define pf(x) printf("%d\n",x)
#define pfl(x) printf("%lld\n",x)
#define pff(x) printf("%lf\n",x)
#define N 50005
#define M 4000009
#define pi acos(-1)
#define eps 1e-2
//cout.setf(ios::fixed);
//freopen("out.txt","w",stdout);
using namespace std;
typedef long long ll;
typedef double db;
const ll mod=1e9+7;
double a[N];
struct tre
{
int len;///這個區間被覆蓋的長度
int f;///表示這個區間被重複覆蓋了幾次
int lc,rc;///表示這個節點左右兩個端點是否被覆蓋(0表示沒有被覆蓋,1表示有被覆蓋)
int num;///這個區間有多少條線段(這個區間被多少條線段覆蓋)
///len用來計算橫線 num用來計算豎線
}t[N];
struct node
{
double lx,rx,y;
int flag;
node(){}
node(double a,double b,double c,double d)
{
lx=a,rx=b,y=c,flag=d;
}
bool operator<(const node b) const
{
return y<b.y;
}
}line[N];
int findx(double x,int n)
{
return lower_bound(a+1,a+1+n,x)-a;
}
void push_up(int u,int l,int r)
{
if(t[u].f)
{
t[u].len=a[r+1]-a[l];
t[u].lc=t[u].rc=t[u].num=1;
}
else if(l==r)
{
t[u].lc=t[u].rc=t[u].num=t[u].len=0;
}
else
{
t[u].len=t[u<<1].len+t[u<<1|1].len;
t[u].lc=t[u<<1].lc;
t[u].rc=t[u<<1|1].rc;
t[u].num=t[u<<1].num+t[u<<1|1].num-(t[u<<1].rc&t[u<<1|1].lc);
}
}
void update(int u,int l,int r,int tl,int tr,int x)
{
if(tr<l||tl>r) return ;
if(tl<=l&&r<=tr)
{
t[u].f+=x;
push_up(u,l,r);
return ;
}
int mid=(l+r)>>1;
update(u<<1,l,mid,tl,tr,x);
update(u<<1|1,mid+1,r,tl,tr,x);
push_up(u,l,r);
}
int main()
{
int n,m;
while(~sd(m)&&m)
{
mem(t,0);
n=0;
fup(i,1,m)
{
double x1,x2,y1,y2;
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
line[++n]=node(x1,x2,y1,1);
a[n]=x1;
line[++n]=node(x1,x2,y2,-1);
a[n]=x2;
};
sort(a+1,a+1+n);
sort(line+1,line+1+n);
int len=1;
for(int i=2; i<=n; i++)
if(a[i]!=a[i+1]) a[++len]=a[i];
// cout<<len<<' '<<n<<endl;
double ans=0,last=0;
fup(i,1,n)
{
int l=findx(line[i].lx,len);
int r=findx(line[i].rx,len)-1;
update(1,1,len,l,r,line[i].flag);
// cout<<l<<' '<<line[i].y<<endl;
ans+=fabs(t[1].len-last);
ans+=(line[i+1].y-line[i].y)*t[1].num*2;
last=t[1].len;
// cout<<ans<<endl;
}
printf("%.0lf\n",ans);
}
}
相關推薦
【線段樹+掃描線】&矩形覆蓋求面積/周長問題(POJ
#include<stdio.h> #include<string.h> #include<string> #include<math.h> #include<algorithm> #include
【POJ1171】【線段樹+掃描線】【矩形周長】【坑區間要分3類討論】
Language: Default Picture Time Limit: 200
bzoj 1645: [Usaco2007 Open]City Horizon 城市地平線【線段樹+hash】
ash 離散化 hash pan != 題目 getchar() cit names bzoj題面什麽鬼啊…… 題目大意:有一個初始值均為0的數列,n次操作,每次將數列(ai,bi-1)這個區間中的數與ci取max,問n次後元素和 離散化,然後建立線段樹,每次修改在區間上打
BZOJ5334 [TJOI2018] 數學計算 【線段樹分治】
amp IT bit 分治 continue lse col %d ++ 題目分析: 大概是考場上的簽到題。首先mod不是質數,所以不能求逆元。註意到有加入操作和刪除操作。一個很典型的想法就是線段樹分治。建立時間線段樹然後只更改有影響的節點,最後把所有標記下傳。時間復雜
【HDU1698】 Just a Hook 【線段樹入門】
uil 機器 連續 fin case using -- pre 上一個 原題:原題鏈接 題意:(機器翻譯的...) 讓我們將鉤子的連續金屬棒從1到N編號。對於每次操作,Pudge可以將連續的金屬棒(從X到Y編號)改為銅棒,銀棒或金棒。 鉤的總值計算為N個金屬棒的值的總和。更
HDU1166敵兵布陣【線段樹入門】
sum char mes sca 敵兵布陣 bsp cas i++ 線段樹 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using n
【SDOI2017】樹點染色【線段樹+LCT】
get d+ i++ read 改變 rotate def 維護 n) 本來只是想練練LCT,沒想到是個線段樹 對於操作1:誒新的顏色?這不是access嗎? 也就是說,我們用一棵splay來表示一種顏色 操作2直接在LCT上亂搞…… 不對啊,操作3要查子樹 誒好像是靜態的
【線段樹模板】區間修改區間求和
蒟蒻線上段樹的路上繼續前進,lazy的出題人的奇思妙想——延遲標記震撼了他。。 線段樹模板題(二)——區間修改與查詢區間和:區間修改區間求和 【題目描述】 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數加上x 2.求出某區間每一個數的和
hdu 5828 Rikka with Sequence 【線段樹+優化】
題意:給你n個數,q個操作,操作k,l,r,k=1時 區間[l,r]每個數加x,k=2時,區間[l,r]每個數開平方,k=3時,求區間[l,r]的和。 分析:我們知道一個數多次開平方會變成1,但是這裡的1操作會使這個數的值增大,所以直接判斷一個區間是否為1肯定超時。 官方
線段樹、掃描線、離散化求面積並(hdu1542)
題目連結: https://vjudge.net/problem/HDU-1542 大牛部落格連結:http://blog.csdn.net/u013480600/article/details/22548393 講解的很生動。 分析: 首先我們將矩形
【劍指Offer】矩形覆蓋
題目描述 我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法? 解法1 一開始嘗試解這道題的時候其實有些不知道怎麼下手,花了很長時間。後來才發現可以利用遞迴的思想,將n的值不斷放小到某個可以直接知道結果的值。雖然直接實現遞迴的演算法可
hdu 1166 敵兵布陣【線段樹】(求給定區間和)
tar 每次 pre 研究 amp sin des ++ 無奈 題目鏈接:https://vjudge.net/contest/182746#problem/B
【線段樹求區間第一個不大於val的值】Lpl and Energy-saving Lamps
所有 href const clas main include uri i++ ant https://nanti.jisuanke.com/t/30996 線段樹維護區間最小值,查詢的時候優先向左走,如果左邊已經找到了,就不用再往右了。 一個房間裝滿則把權值標記為INF,
線段樹+掃描線【p1884】[Usaco12FEB]過度種植(銀)Overplanting …
Description 在一個笛卡爾平面座標系裡(則X軸向右是正方向,Y軸向上是正方向),有\(N(1<=N<=1000)\)個矩形,第i個矩形的左上角座標是\((x1, y1)\),右下角座標是\((x2,y2)\)。問這\(N\)個矩形所覆蓋的面積是多少?注意:被重複覆蓋的區域的面積
線段樹+掃描線【bzoj1645】[USACO07OPEN]城市的地平線City Horizon
Description 約翰帶著奶牛去都市觀光。在落日的餘暉裡,他們看到了一幢接一幢的摩天高樓的輪廓在地平線 上形成美麗的圖案。以地平線為 X 軸,每幢高樓的輪廓是一個位於地平線上的矩形,彼此間可能有 重疊的部分。奶牛一共看到了 N 幢高樓,第 i 幢樓的高度是 Hi,兩條邊界輪廓在地平線上的座標是
ZYH的斐波那契數列【線段樹動態開點+矩陣快速冪求斐波那契】
描述 ZYH最近研究數列研究得入迷啦! 現在有一個斐波拉契數列(f[1]=f[2]=1,對於n>2有f[n]=f[n-1]+f[n-2]), 但是斐波拉契數列太簡單啦,於是ZYH把它改成了斐波拉契的字首和的數列{Si}(S[1]=1,對於n>1,有S[n]=S[n-1]+f[
【HDU】1394Minimum Inversion Number-(線段樹單點更新,求出逆序數)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 25122 &n
poj 2828 Buy Tickets 【線段樹點更新】
clu input family freopen rst cst href targe pri 題目:poj 2828 Buy Tickets 題意:有n個人排隊,每一個人有一個價值和要插的位置,然後當要插的位置上有人時全部的人向後移動一位當這個插入到這兒,假設沒有
【線段樹】I Hate It
程序 printf 處理 其中 bmi ott 學生 ref 兩個 I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub
【線段樹】Mayor's posters
while campaign segments ace form ges image discus divide [poj2528]Mayor‘s posters Time Limit: 1000MS Memory Limit: 65536K