• BZOJ1818 [Cqoi2010]内部白点 扫描线/线段求交


    毫无头绪。。hint了一波瞄到了用扫描线做线段求交

    想了想开始码。。过样例之后谜之wa

    估计是加line的时候没把点做第二维排序,line不是一段一段进去的,加上就过了

    //#include<bits/stdc++.h>  
    #pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>  
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip>  
    using namespace std;  
    #define ll long long  
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++)  
    const int inf=0x3f3f3f3f;  
     
    const int maxn=2e5+5;    
     
    int n,hash[maxn<<1];
    
    struct dot{int x,y;}a[maxn];
    bool cmp1(dot a,dot b){if(a.x==b.x){return a.y<b.y;}return a.x<b.x;}
    bool cmp2(dot a,dot b){if(a.y==b.y){return a.x<b.x;}return a.y<b.y;}
    
    struct Line{int x1,x2,y,kind;}line[maxn<<1];	//-1竖出1竖入,0横
    bool cmp(Line a,Line b){
    	if(a.y==b.y)return a.kind<b.kind;
    	return a.y<b.y;
    }
    
    int sum[maxn<<2];
    void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}
    void update(int a,int b,int c,int l,int r,int rt){
    	if(l==r){sum[rt]+=c;return;}
    	int m=l+r>>1;
    	if(a<=m)update(a,b,c,l,m,rt<<1);
    	else update(a,b,c,m+1,r,rt<<1|1);
    	pushup(rt);
    }
    int query(int a,int b,int l,int r,int rt){
    	if(a<=l&&b>=r)return sum[rt];
    	int m=l+r>>1;
    	int ret=0;
    	if(a<=m)ret+=query(a,b,l,m,rt<<1);
    	if(b> m)ret+=query(a,b,m+1,r,rt<<1|1);
    	return ret;
    }
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1,x,y;i<=n;i++){
    		scanf("%d%d",&x,&y);
    		a[i]=(dot){x,y};
    		hash[i]=a[i].x;
    	}
    	sort(hash+1,hash+1+n);
    	int num=1;
    	for(int i=2;i<=n;i++){
    		if(hash[i]!=hash[i-1])hash[++num]=hash[i];
    	}
    
    	int tot=0;
    	sort(a+1,a+1+n,cmp1);
    	for(int i=2;i<=n;i++){
    		if(a[i].x==a[i-1].x){
    			int y1=min(a[i].y,a[i-1].y);
    			int y2=max(a[i].y,a[i-1].y);
    			line[++tot]=(Line){a[i].x,a[i].x,y1,1};
    			line[++tot]=(Line){a[i].x,a[i].x,y2,-1};
    		}
    	}
    	sort(a+1,a+1+n,cmp2);
    	for(int i=2;i<=n;i++){
    		if(a[i].y==a[i-1].y){
    			int x1=min(a[i].x,a[i-1].x);
    			int x2=max(a[i].x,a[i-1].x);
    			line[++tot]=(Line){x1,x2,a[i].y,0};
    		}
    	}
    	sort(line+1,line+1+tot,cmp);
    	int ans=0;
    	for(int i=1;i<=tot;i++){
    		//cout<<i<<" "<<sum[1]<<endl;
    		Line now=line[i];
    
    		if(now.kind!=0){
    			int l=lower_bound(hash+1,hash+1+num,now.x1)-hash;
    			if(now.kind==1)update(l,l,1,1,num,1);
    			else update(l,l,-1,1,num,1);
    
    		}else{
    			int l=lower_bound(hash+1,hash+1+num,now.x1)-hash;
    			int r=lower_bound(hash+1,hash+1+num,now.x2)-hash;
    
    			if(r==l+1)continue;
    
    			ans+=query(l+1,r-1,1,num,1);
    		}
    		//cout<<i<<" "<<query(2,2,1,num,1)<<endl;
    	}
    	printf("%d
    ",ans+n);
    }


  • 相关阅读:
    Linux中断的系统调用
    线程的概念
    C++ 虚函数表浅析
    C++虚函数工作原理
    深入浅出单实例Singleton设计模式
    《角斗士》一个帝国的史诗绝唱
    《妖猫传》大唐盛世背后那些事
    程序员之路
    职业规划
    一些重要的算法
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611208.html
Copyright © 2020-2023  润新知