1. 程式人生 > >【線段樹+掃描線】&矩形覆蓋求面積/周長問題(POJ

【線段樹+掃描線】&矩形覆蓋求面積/周長問題(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

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[

HDU1394Minimum 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