zoukankan      html  css  js  c++  java
  • 扫描线

    其实并不能很熟练的写出代码,开此博客简单整理一下代码实现。

    扫描线使用线段树的操作来实现。

    对于这个线段树,可不是简单的线段树。我们维护的区间也很神奇……

    对于 (l,r) 我们其实维护的是区间 (left[que[l],que[r+1] ight))

    因为对于每一个区间加操作,一定会有一个相对应的区间减操作,所以标记不必下移,也不必更新……

    在对边进行排序的时候,需要按照两个关键字进行排序

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    #define int long long
    #define mid (l+r>>1)
    
    using namespace std;
    
    int read()
    {
    	int a = 0,x = 1;char ch = getchar();
    	while(ch > '9' || ch < '0') {if(ch == '-') x = -1;ch = getchar();}
    	while(ch >= '0' && ch <= '9') {a = a*10 + ch-'0';ch = getchar();}
    	return a*x;
    }
    const int N=1e6+7;
    struct node{
    	int l,r,h,x;
    	friend bool operator < (node a,node b) {return a.h!=b.h?a.h < b.h:a.x>b.x;}
    }arr[N];
    int n,cnt,que[N],tot,ans;
    int a[N],b[N],c[N],d[N];
    
    int tre[N],lazy[N];
    
    void pushup(int root,int l,int r)
    {
    	if(lazy[root]) tre[root] = que[r+1]-que[l];
    	else tre[root] = tre[root<<1]+tre[root<<1|1];
    }
    
    void modify(int root,int l,int r,int L,int R,int x)
    {
    	if(que[l] >= R || que[r+1] <= L) return;
    	if(que[l] >= L && que[r+1] <= R) {
    		lazy[root] += x;
    	} else {
    		modify(root<<1,l,mid,L,R,x);
    		modify(root<<1|1,mid+1,r,L,R,x);
    	}
    	pushup(root,l,r);
    }
    
    void solve()
    {
    	for(int i = 1,tmp=0;i <= tot;i ++) {
    		modify(1,1,cnt-1,arr[i].l,arr[i].r,arr[i].x);
    		ans += abs(tmp-tre[1]);
    		tmp = tre[1];
    	}
    }
    
    signed main()
    {
    	// freopen("in.in","r",stdin);
    	// freopen("out.out","w",stdout);
    	n = read();
    	for(int i = 1;i <= n;i ++) {
    		a[i] = read(),b[i] = read(),c[i] = read(),d[i] = read();
    	}
    
    	for(int i = 1;i <= n;i ++){
    		que[++cnt] = a[i],que[++cnt] = c[i];
    		arr[++tot] = (node){a[i],c[i],b[i],1};
    		arr[++tot] = (node){a[i],c[i],d[i],-1};
    	}
    	sort(que+1,que+1+cnt);
    	cnt = unique(que+1,que+1+cnt) - que - 1;
    	que[0] = -1e18,que[cnt+1] = 1e18;
    	sort(arr+1,arr+1+tot);
    	solve();
    
    	tot = cnt = 0;
    	for(int i = 1;i <= n;i ++){
    		que[++cnt] = b[i],que[++cnt] = d[i];
    		arr[++tot] = (node){b[i],d[i],a[i],1};
    		arr[++tot] = (node){b[i],d[i],c[i],-1};
    	}
    	sort(que+1,que+1+cnt);
    	cnt = unique(que+1,que+1+cnt) - que - 1;
    	que[0] = -1e18,que[cnt+1] = 1e18;
    	sort(arr+1,arr+1+tot);
    	solve();
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    c#结构体、打他table、excel、csv互转
    WPF 自定义图表(柱状图,曲线图)
    NemaStudio船舶模拟软件下载及破解
    点双连通分量
    HDU4612 Warm up
    边双连通分量
    [Jsoi2010]连通数
    Intern Day73
    Intern Day72
    Intern Day70
  • 原文地址:https://www.cnblogs.com/nao-nao/p/14034620.html
Copyright © 2011-2022 走看看