<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【學習筆記】掃描線

      一.前言

      早就學了掃描線了,但是有一道題當時沒做,現(xiàn)在才做,于是就來寫寫學習筆記。
      哎我學習筆記前面咋老是這么多廢話啊

      二.定義

      掃描線其實是一種思想,就是遍歷某個值并將其加入數(shù)據(jù)結構,同時動態(tài)地解決一些問題。
      聽起來很抽象,那就看例題吧。

      三.例題

      [poj1151]亞特蘭蒂斯

      求矩形面積并。想象一條線從下往上掃整個平面,就能求出在每個矩形的上下邊界處橫向覆蓋的距離。畫出來長這樣:

      我想這也是這個思想叫掃描線的原因。
      因此我們從下往上插入矩形的上下邊,在下面加入,在上面刪除,順帶統(tǒng)計答案就好了。

      Code
      #include<bits/stdc++.h>
      #define ll long long
      #define il inline
      #define ld long double
      #define x1(i) a[i].x1
      #define x2(i) a[i].x2
      #define y(i) a[i].y
      #define tag(i) a[i].tag
      #define lid id<<1
      #define rid id<<1|1
      #define l(id) tr[id].l
      #define r(id) tr[id].r
      #define cnt(id) tr[id].cnt
      #define len(id) tr[id].len
      #define lb lower_bound
      using namespace std;
      const int maxn=1e4+5;
      int n,m;
      struct line{
      	ld x1,x2,y;
      	int tag;
      	il bool operator<(const line &x){return y<x.y;}
      }a[maxn<<1];
      ld b[maxn<<1],ans;
      struct seg{
      	int l,r,cnt;
      	ld len;
      }tr[maxn<<3];
      il void build(int id,int l,int r){
      	tr[id]=(seg){l,r,0,0};
      	if(l==r) return ;
      	int mid=(l+r)>>1;
      	build(lid,l,mid),build(rid,mid+1,r);
      }
      il void pushup(int id){
      	int l=l(id),r=r(id);
      	if(cnt(id)) len(id)=b[r+1]-b[l];
      	else len(id)=len(lid)+len(rid);
      }
      il void upd(int id,int l,int r,int tag){
      	if(l(id)>=l and r(id)<=r){
      		cnt(id)+=tag;
      		pushup(id);
      		return ;
      	}
      	int mid=(l(id)+r(id))>>1;
      	if(l<=mid) upd(lid,l,r,tag);
      	if(r>mid) upd(rid,l,r,tag);
      	pushup(id);
      }
      int main(){
      	for(int T=1;;T++){
      		scanf("%d",&n);
      		if(!n) break;
      		for(int i=1;i<=n;i++){
      			scanf("%Lf%Lf%Lf%Lf",&x1(i),&y(i),&x2(i),&y(i+n));
      			x1(i+n)=x1(i),x2(i+n)=x2(i);
      			tag(i)=1,tag(i+n)=-1;
      			b[i]=x1(i),b[i+n]=x2(i);
      		}
      		n<<=1;
      		sort(a+1,a+n+1),sort(b+1,b+n+1);
      		m=unique(b+1,b+n+1)-b-1;
      		ans=0,build(1,1,m-1);
      		for(int i=1,l,r;i<n;i++){
      			l=lb(b+1,b+m+1,x1(i))-b;
      			r=lb(b+1,b+m+1,x2(i))-b;
      			upd(1,l,r-1,tag(i));
      			ans+=len(1)*(y(i+1)-y(i));
      		}
      		printf("Test case #%d\nTotal explored area: %.2Lf\n",T,ans);
      	}
      	return 0;
      }
      

      [IOI1998] [USACO5.5] 矩形周長Picture

      求周長,顯然直接掃描線就好了。橫著跑一遍再豎著跑一遍。

      Code
      #include<bits/stdc++.h>
      #define ll long long
      #define il inline
      #define read(x){\
      	char ch;\
      	int fu=1;\
      	while(!isdigit(ch=getchar()))\
      		fu-=(ch=='-')<<1;\
      	x=ch&15;\
      	while(isdigit(ch=getchar()))\
      		x=(x<<1)+(x<<3)+(ch&15);\
      	x*=fu;\
      }
      #define lid tr[id].ls
      #define rid tr[id].rs
      #define len(id) tr[id].len
      #define cnt(id) tr[id].cnt
      #define lb lower_bound
      using namespace std;
      namespace cplx{bool begin;}
      const int maxn=5e3+5;
      int n,lsh[maxn<<1],tot,num,rt,ans;
      int xa[maxn],ya[maxn],xb[maxn],yb[maxn];
      struct xian{
      	int x1,x2,y,tag;
      	il bool operator<(const xian &x){return y<x.y;}
      }a[maxn<<1];
      struct seg{int ls,rs,len,cnt;}tr[maxn<<2];
      il void build(int &id,int l,int r){
      //	cout<<l<<" "<<r<<"\n";
      	id=++num;
      	len(id)=cnt(id)=lid=rid=0;
      	if(l==r) return ;
      	int mid=(l+r)>>1;
      	build(lid,l,mid);
      	build(rid,mid+1,r);
      }
      il void pushup(int id,int l,int r){
      	if(cnt(id)) len(id)=lsh[r+1]-lsh[l];
      	else len(id)=len(lid)+len(rid);
      }
      il void upd(int id,int L,int R,int l,int r,int val){
      	if(L>=l and R<=r)
      		return (void)(cnt(id)+=val,pushup(id,L,R));
      	int mid=(L+R)>>1;
      	if(l<=mid) upd(lid,L,mid,l,r,val);
      	if(r>mid) upd(rid,mid+1,R,l,r,val);
      	pushup(id,L,R);
      //	cout<<L<<" "<<R<<" "<<cnt(id)<<"\n";
      }
      il void solve(){
      	tot=num=rt=0;
      	for(int i=1;i<=n;i++)
      		lsh[++tot]=a[i].x1,lsh[++tot]=a[i].x2;
      	sort(lsh+1,lsh+tot+1);
      	tot=unique(lsh+1,lsh+tot+1)-lsh-1;
      //	cout<<tot<<"\n";
      //	for(int i=1;i<=tot;i++) cout<<lsh[i]<<" ";
      //	puts("");
      	n<<=1;
      	sort(a+1,a+n+1);
      	build(rt,1,tot-1);
      //	for(int id=1;id<=num;id++)
      //		cout<<id<<" "<<lid<<" "<<rid<<" "<<len(id)<<" "<<cnt(id)<<"\n";
      //	puts("");
      	for(int i=1,lst=0,t1,t2;i<=n;i++){
      		t1=lb(lsh+1,lsh+tot+1,a[i].x1)-lsh;
      		t2=lb(lsh+1,lsh+tot+1,a[i].x2)-lsh;
      //		cout<<t1<<" "<<t2<<"\n";
      		upd(rt,1,tot-1,t1,t2-1,a[i].tag);
      		ans+=abs(len(1)-lst);
      		lst=len(1);
      //		cout<<a[i].x1<<" "<<a[i].x2<<" "<<a[i].y<<" "<<a[i].tag<<" ";
      //		puts("");
      //		cout<<t1<<" "<<t2<<" "<<lst<<" "<<cnt(1)<<"\n";
      	}
      	n>>=1;
      }
      namespace cplx{
      	bool end;
      	il double usdmem(){return (&begin-&end)/1048576.0;}
      }
      int main(){
      	read(n);
      //	cout<<n<<"\n";
      	for(int i=1;i<=n;i++){
      		read(xa[i])read(ya[i]);
      		read(xb[i])read(yb[i]);
      //		cout<<xa[i]<<" "<<ya[i]<<" "<<xb[i]<<" "<<yb[i]<<"\n";
      	}
      	for(int i=1;i<=n;i++){
      		a[i].x1=a[i+n].x1=xa[i];
      		a[i].x2=a[i+n].x2=xb[i];
      		a[i].y=ya[i],a[i+n].y=yb[i];
      		a[i].tag=1,a[i+n].tag=-1;
      	}
      	solve();
      //	cout<<n<<"\n";
      	for(int i=1;i<=n;i++){
      		a[i].x1=a[i+n].x1=ya[i];
      		a[i].x2=a[i+n].x2=yb[i];
      		a[i].y=xa[i],a[i+n].y=xb[i];
      		a[i].tag=1,a[i+n].tag=-1;
      	}
      	solve();
      	printf("%d",ans);
      	return 0;
      }
      

      [poj2482]窗口的星星

      考慮一個星星,能覆蓋它的矩形的右上角是在一個區(qū)間 \([x,x+W-1]\) 中的。于是掃描線區(qū)間修改整體查詢最大值即可。

      Code
      #include<bits/stdc++.h>
      #define int long long
      #define il inline
      #define pb push_back
      #define lwrb lower_bound
      using namespace std;
      namespace asbt{
      namespace cplx{bool begin;}
      const int maxn=1e4+5;
      int n,W,H,lsh[maxn],cnt,rt;
      int tr[maxn*70],tag[maxn*70];
      int ls[maxn*70],rs[maxn*70];
      struct node{
      	int x,y,c;
      }a[maxn];
      vector<int> cun[maxn];
      il void pushup(int id){
      	tr[id]=max(tr[ls[id]],tr[rs[id]]);
      }
      il void pushtag(int id,int v){
      	tr[id]+=v,tag[id]+=v;
      }
      il void pushdown(int id){
      	if(tag[id]){
      		if(!ls[id]){
      			ls[id]=++cnt;
      			tr[cnt]=tag[cnt]=0;
      			ls[cnt]=rs[cnt]=0;
      		}
      		if(!rs[id]){
      			rs[id]=++cnt;
      			tr[cnt]=tag[cnt]=0;
      			ls[cnt]=rs[cnt]=0;
      		}
      		pushtag(ls[id],tag[id]);
      		pushtag(rs[id],tag[id]);
      		tag[id]=0;
      	}
      }
      il void upd(int &id,int L,int R,int l,int r,int v){
      	if(!id){
      		id=++cnt;
      		tr[id]=tag[id]=0;
      		ls[id]=rs[id]=0;
      	}
      	if(L>=l&&R<=r){
      		pushtag(id,v);
      		return ;
      	}
      	pushdown(id);
      	int mid=(L+R)>>1;
      	if(l<=mid){
      		upd(ls[id],L,mid,l,r,v);
      	}
      	if(r>mid){
      		upd(rs[id],mid+1,R,l,r,v);
      	}
      	pushup(id);
      }
      il void solve(){
      	int tot=0;
      	for(int i=1;i<=n;i++){
      		scanf("%lld%lld%lld",&a[i].x,&a[i].y,&a[i].c);
      		lsh[++tot]=a[i].y;
      	}
      	sort(lsh+1,lsh+n+1);
      	tot=unique(lsh+1,lsh+n+1)-lsh-1;
      	for(int i=1;i<=n;i++){
      		cun[lwrb(lsh+1,lsh+tot+1,a[i].y)-lsh].pb(i);
      	}
      	int ans=0;
      	cnt=rt=0;
      	for(int i=1,p=1,q;i<=tot;i++){
      		for(int j:cun[i]){
      			upd(rt,0,1ll<<31,a[j].x,a[j].x+W-1,a[j].c);
      		}
      		q=lwrb(lsh+1,lsh+tot+1,lsh[i]-H+1)-lsh-1;
      		while(p<=q){
      			for(int j:cun[p]){
      				upd(rt,0,1ll<<31,a[j].x,a[j].x+W-1,-a[j].c);
      			}
      			p++;
      		}
      		ans=max(ans,tr[rt]);
      	}
      	printf("%lld\n",ans);
      	for(int i=1;i<=tot;i++){
      		cun[i].clear();
      	}
      }
      namespace cplx{
      	bool end;
      	il double usdmem(){return (&begin-&end)/1048576.0;}
      }
      signed main(){
      //	cout<<cplx::usdmem();
      	while(~scanf("%lld%lld%lld",&n,&W,&H)){
      //		puts("666");
      		solve();
      	}
      	return 0;
      }
      }
      signed main(){return asbt::main();}
      
      posted @ 2025-02-06 21:43  zhangxy__hp  閱讀(42)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 青草青草视频2免费观看| 国产成人综合在线观看不卡| 无码伊人久久大杳蕉中文无码| 最新精品国偷自产在线美女足| 亚洲欧美成人aⅴ在线| 久久久久久久久久久免费精品 | 人妻丝袜无码专区视频网站| 久久亚洲精品中文字幕无| 日韩人妻无码中文字幕视频| 国产人伦精品一区二区三| 久久午夜无码鲁丝片直播午夜精品 | 国产第一区二区三区精品| 华人在线亚洲欧美精品| 2020国产激情视频在线观看| 成人区人妻精品一区二蜜臀| 国产在线98福利播放视频| 这里只有精品免费视频| 国产三级国产精品久久成人| 亚洲欧洲一区二区精品| 国产成人精品午夜二三区| 国产男女猛烈无遮挡免费视频| 97se亚洲国产综合自在线观看| 国产成人无码免费看视频软件| 日韩精品中文字幕人妻| 亚洲国产一区二区三区亚瑟| 国产一级片内射在线视频| 视频一区视频二区视频三区| 国产成人亚洲综合| 91亚洲国产三上悠亚在线播放 | 十八禁午夜福利免费网站| 一区二区三区不卡国产| 国产尤物精品自在拍视频首页| 久久精品国产精品亚洲艾| 凸凹人妻人人澡人人添| 高级艳妇交换俱乐部小说| 最近中文字幕完整版hd| 免费天堂无码人妻成人av电影 | 国产一区二区三区在线观看免费 | 精品国产AV最大网站| 国产热A欧美热A在线视频| 日韩一区二区三区av在线|