线段树处理面积交并 不懂不懂

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define rt return
#define sf scanf
#define pf printf
#define si(n) sf("%d",&n)
#define pi(n) pf("%d",n)
#define REP0(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<=(n);i++)
#define REP(i,s,n) for(int i=s;i<=(n);i++)
#define db double
#define pb push_back
#define LL long long
#define INF 0x3fffffff
#define eps 1e-8
#define PI acos(-1)
#define maxn 1100
using namespace std;
int n;
struct node{
    LL x1,y1,x2,y2;
}p[maxn];
int xx[maxn*2],yy[maxn*2];
int main(){
    #ifdef ACBang
//    freopen("in.txt","r",stdin);
    #endif
    int CAS;sf("%d",&CAS);
    while(CAS--){
        sf("%d",&n);
        REP0(i,n){
            LL x1,y1,x2,y2;
            sf("%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2);
            p[i].x1=x1;p[i].x2=x2;p[i].y1=y1;p[i].y2=y2;
            xx[i<<1]=x1;
            xx[i<<1|1]=x2;
            yy[i<<1]=y1;
            yy[i<<1|1]=y2;
        }
        sort(xx,xx+2*n);
        sort(yy,yy+2*n);
//        int x_cnt = unique(xx,xx+2*n)-xx;
//        int y_cnt = unique(yy,yy+2*n)-yy;
        LL ans=0;
        REP0(i,(n<<1)-1){
            REP0(j,(n<<1)-1){
                REP0(k,n){
                    if(p[k].x1<=xx[i]&&xx[i+1]<=p[k].x2&&p[k].y1<=yy[j]&&yy[j+1]<=p[k].y2){
                        ans+=(xx[i+1]-xx[i])*(yy[j+1]-yy[j]);
                        break;
                    }
                }
            }
        }
        pf("%I64d\n",ans);
    }
    rt 0;
}
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define rt return
#define sf scanf
#define si(n) sf("%d\n",&n)
#define pf printf
#define REP0(i,n) for(int i=0;i<(n);i++)
#define REP1(i,n) for(int i=1;i<=(n);i++)
#define REP(i,s,n) for(int i=s;i<=(n);i++)
#define db double
#define pb push_back
#define LL long long
#define INF 0x3fffffff
#define eps 1e-8
#define PI acos(-1)
#define N 20010
using namespace std;
struct seg{
    db x1,x2,y;
    int mark;
    seg(){}
    seg(db a,db b,db c,int d):x1(a),x2(b),y(c),mark(d){}
    bool operator<(const seg& a)const{return y<a.y;}
};
struct node{
    db l,r,len,len2;
    int cov;
    node *left,*right;
    node(db a,db b){
        l=a;r=b;len=len2=0;cov=0;
        left=right=NULL;
    }
};
db xis[N*2];
seg s[N*2];
node *build(int s,int t){
    node *root = new node(xis[s],xis[t] );
    if(t>s+1){
        int m=(s+t)>>1;
        root->left = build(s,m);
        root->right = build(m,t);
    }
    return root;
}
void updata(node *root){
    root->len=0;
    if(root->cov >0)root->len = root->r - root->l;
    else{
        if(root->left )root->len+=root->left->len;
        if(root->right)root->len+=root->right->len;
    }
    root->len2=0;
    if(root->cov >1)root->len2=root->r - root->l;
    else if(root->cov ==1){
        if(root->left )root->len2+=root->left->len;
        if(root->right)root->len2+=root->right->len;
    }
    else {
        if(root->left )root->len2+=root->left->len2;
        if(root->right)root->len2+=root->right->len2;
    }
}
void insert(node *root,seg line){
    if(root->l==line.x1 && root->r==line.x2)root->cov+=line.mark;
    else if(root->left->r >=line.x2)insert(root->left,line);
    else if(root->right->l <=line.x1)insert(root->right,line);
    else{
        seg f=line;
        f.x2=root->left->r;
        insert(root->left,f);
        f=line;
        f.x1=root->left->r;
        insert(root->right,f);
    }
    updata(root);
}
void bbt(int &cnt,int &flag,db x1,db y1,db x2,db y2){
    if(x1==x2||y1==y2)return ;
    xis[cnt++]=x1;
    xis[cnt++]=x2;
    s[flag++]=seg(x1,x2,y1,1);
    s[flag++]=seg(x1,x2,y2,-1);
}
int read(int &n){
    db x1,x2,y1,y2;
    int cnt=0,flag=0;
    for(int i=0;i<n;i++){
        sf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        bbt(cnt,flag,x1,y1,x2,y2);
    }
    sort(xis,xis+cnt);
    sort(s,s+flag);
    n=unique(xis,xis+cnt)-xis;
    return flag;
}
void out(node *root);
int main(){
    #ifdef ACBang
    freopen("in.txt","r",stdin);
    #endif
    int CAS;sf("%d",&CAS);
    while(CAS--){
        int n;
        sf("%d",&n);
        int cnt=read(n);
        node *root=build(0,n-1);
        out(root);
        db sum=0,ans=0;
        for(int i=0;i<cnt-1;i++){
            insert(root,s[i]);
            sum+=root->len*(s[i+1].y-s[i].y );
            ans+=root->len2*(s[i+1].y-s[i].y );
            cout<<root->len*(s[i+1].y-s[i].y )<<endl;
            out(root);
        }
        pf("%.0f\n",sum);
    }
    rt 0;
}
void out(node *root){
    cout<<root->l<<" "<<root->r<<" ";
    cout<<root->cov<<" "<<root->len<<" "<<endl;
    if(root->left)out(root->left);
    if(root->right)out(root->right);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值