2 条题解

  • 1
    @ 2026-6-30 14:39:56
    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    #define lc(p) (p << 1)
    #define rc(p) ((p << 1) | 1) 
    const int N = 2e5 + 10;
    
    struct Line {
    	int p;
    	int st, ed;
    	int flg;
    } L[N];   // 一条竖线:x 坐标是 p,y 的范围是 st 至 ed 
    int s[N * 2], cnt;
    
    struct trnode {
    	int l, r, c;
    	LL len;
    } tr[N << 3];
    
    bool cmp(Line la, Line lb) {
    	return la.p < lb.p;
    }
    
    void pushup(int p) {
    	if (tr[p].c > 0) {
    		tr[p].len = s[tr[p].r] - s[tr[p].l];
    	}
    	else {
    		tr[p].len = tr[lc(p)].len + tr[rc(p)].len;
    	}
    }
    
    void bt(int p, int l, int r) {
    	tr[p] = {l, r, 0, 0};
    	if (l + 1 == r) {
    		return ;
    	}
    	
    	int mid = (l + r) >> 1;
    	bt(lc(p), l, mid);
    	bt(rc(p), mid, r); // 树里面是区间段不是点,所以不用 r + 1 
    }
    
    void change(int p, int l, int r, int c) {
    	if (r <= s[tr[p].l] || l >= s[tr[p].r]) {
    		// 相等的情况说明只是区间段的边界点擦边
    		// 并不代表区间段相交,所以也要 return 
    		return ;
    	}
    	if (l <= s[tr[p].l] && s[tr[p].r] <= r) {
    		tr[p].c += c;
    		pushup(p);
    		return ;
    	}
    	
    	change(lc(p), l, r, c);
    	change(rc(p), l, r, c);
    	pushup(p);
    } 
    
    int main() {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	
    	int n;
    	cin >> n;
    	int xa, ya, xb, yb;
    	for (int i = 1; i <= n; i ++) {
    		cin >> xa >> ya >> xb >> yb;
    		L[i] = {xa, ya, yb, 1};
    		L[i + n] = {xb, ya, yb, -1};
    		s[i] = ya; s[i + n] = yb;
    	}
    	
    	n *= 2;
    	sort (s + 1, s + n + 1);
    	cnt = unique(s + 1, s + n + 1) - (s + 1);
    	sort (L + 1, L + n + 1, cmp);
    	
    	bt(1, 1, cnt);
    	LL ans = 0;
    	for (int i = 1; i <= n; i ++) {
    		change(1, L[i].st, L[i].ed, L[i].flg);
    		ans += (L[i + 1].p - L[i].p) * tr[1].len;
    	}
    	
    	cout << ans << "\n";
    	
    	return 0;
    }
    
    
    • -1
      @ 2025-10-8 16:51:35

      C15【模板】扫描线算法

      #include<bits/stdc++.h>
      #define lc(p) (p<<1)
      #define rc(p) (p<<1|1)
      #define LL long long
      using namespace std;
      const int N=2e5+10;
      struct Line{LL p,st,ed,flg; }L[N];// 一条竖线:x坐标是p,y的范围是st至ed 
      bool cmp(Line n1,Line n2){return n1.p<n2.p;} 
      LL lsh[N];
      struct trnode{int l,r,c;LL len;}tr[N<<3];
      void pushup(int p)
      {
      	if(tr[p].c>0) tr[p].len=lsh[tr[p].r]-lsh[tr[p].l];
      	else          tr[p].len=tr[lc(p)].len+tr[rc(p)].len ;
      }
      void bt(int p,int l,int r)
      {
      	tr[p]=trnode{l,r,0,0};
      	if(l+1==r)return ;
      	int m=(l+r)>>1;
      	bt(lc(p),l,m);bt(rc(p),m,r);
      }
      void change(int p,int l,int r,int c)
      {
      	if(r<=lsh[tr[p].l]||lsh[tr[p].r]<=l)return;
      	if(l<=lsh[tr[p].l]&&lsh[tr[p].r]<=r)
      	{
      		tr[p].c+=c;
      		pushup(p);
      		return ;
      	}
      	change(lc(p),l,r,c);change(rc(p),l,r,c);
      	pushup(p);
      }
      int main()
      {
      	int n;scanf("%d",&n);
      	for(int i=1;i<=n;i++)
      	{
      		LL X1,Y1,X2,Y2;scanf("%lld%lld%lld%lld",&X1,&Y1,&X2,&Y2);
      		L[i]  =Line{X1,Y1,Y2, 1};
      		L[n+i]=Line{X2,Y1,Y2,-1};
      		lsh[i]=Y1;lsh[n+i]=Y2;
      	}
      	sort(lsh+1,lsh+2*n+1);int ln=unique(lsh+1,lsh+2*n+1)-lsh-1;
      	bt(1,1,ln);
      	sort(L+1,L+2*n+1,cmp);
      	LL ans=0;
      	for(int i=1;i<2*n;i++)
      	{
      		change(1,L[i].st,L[i].ed,L[i].flg);
      		ans+=(L[i+1].p-L[i].p)*tr[1].len;
      	}
      	printf("%lld\n",ans);
      	return 0;
      }
      
      • 1

      C15【模板】扫描线 & 矩形面积并

      信息

      ID
      491
      时间
      1000ms
      内存
      512MiB
      难度
      7
      标签
      递交数
      138
      已通过
      33
      上传者