zoukankan      html  css  js  c++  java
  • 动态凸包(询问点是否在凸包内部)

    动态凸包,n次操作,添加一个点,或询问一个点是否在凸包内部.
    ps:询问每次更新后的凸包面积的板子在Hdu板子上.

    typedef long long ll;
    const int MOD = 1e9 + 7;
    const int INF = 0x7fffffff;
    const double eps = 1e-9;
    
    const int N = 1e5 + 50,M = 1e5 + 50;
    
    #define MP make_pair
    typedef pair<int,int>PII;
    map<int,int>convex[2];
    map<int,int>::iterator p,q,it,it1,it2;
    
    ll Cross(PII a,PII b,PII c) {
    	return 1ll*(b.fi-a.fi)*(c.se-a.se)-1ll*(b.se-a.se)*(c.fi-a.fi);
    }
    
    
    //点是否在凸包内部
    bool judge(map<int,int>&st,int x,int y) {
    	if(!st.size())return false;
    	if(st.find(x)!=st.end())return y>=st[x];
    	if(x<st.begin()->fi || (--st.end())->fi < x)return false;
    	p = st.lower_bound(x);
    	q = p,q--;	//找到左右点
    	return Cross(MP(x,y),*q,*p)>=0;
    }
    
    
    void insert(map<int,int>&st,int x,int y) {
    	if(judge(st,x,y))return ;
    	st[x] = y;
    	p = st.upper_bound(x);
    	it = p,it--;
    	it1 = it,it1--;
    	it2 = it1,it2--;
    	if(p != st.end()) {
    		q = p,q++;
    		while(q != st.end() && Cross(MP(x,y),*q,*p)>=0) {
    			st.erase(p);
    			p = q,q ++;
    		}
    	}
    	if(it == st.begin() || it1 == st.begin())return ;
    	while(it1 != st.begin() && Cross(MP(x,y),*it1,*it2)>=0) {
    		st.erase(it1),it1=it2,it2--;
    	}
    }
    
    int n;
    
    void work() {
    	scanf("%d",&n);
    	while(n--) {
    		int op,x,y;
    		scanf("%d%d%d",&op,&x,&y);
    		if(op == 1) {
    			insert(convex[0],x,y);
    			insert(convex[1],x,-y);
    		} else {
    			bool ans1=judge(convex[0],x,y);
    			bool ans2=judge(convex[1],x,-y);
    			if(ans1&&ans2)puts("YES");
    			else puts("NO");
    		}
    	}
    }
    
  • 相关阅读:
    SQL数据转移
    怎么将控制台的打印输出到文本文件中
    用来控制 XML 序列化的属性
    excel内容转成xml
    HTTP状态码
    char、varchar、nchar、nvarchar的区别
    C# Cookie编程
    android的原理--为什么我们不需要手动关闭程序
    HTTP协议及HTTP包
    HTTP 方法:GET 对比 POST
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/15073241.html
Copyright © 2011-2022 走看看