zoukankan      html  css  js  c++  java
  • ZOJ 3511 不相交切切多边形 线段树求最大边数

    题意:

    n多凸边形 m刀 (把n切m刀,问切完后的图形中 最多的边数 是多少)

    切a点-b点

    数据保证切的刀不会相交

    思路:

    2点之间的剩余点数就是边数,

    把a-b距离 近 排序

    切完一刀就统计一下切出来的蛋糕的边数,并舍弃

    [a,b] 表示a,b 点间剩下的点数(就是边数)

    先计算[a,b]的点数, 然后删除(a,b) 区间的点 (注意删除的是(a,b) ,所以实际操作是 删除[a,b] )

    最后要特殊算下 剩下那块的(因为那块没有切)

    #include<iostream>
    #include<stdio.h>
    #include<string>
    #include<string.h>
    #include<algorithm>
    #include<set>
    #include <cstdio>  
    #include <cstring>  
    #include <iostream>  
    #include <math.h>  
    #include <queue>  
    #define N 10100  
    #define M 2000100  
    #define inf64 0x7ffffff  
    #define inf 1073741824  
    #define ll int  
    #define L(x) x<<1  
    #define R(x) x<<1|1  
    #define Mid(x,y) (x+y)>>1  
    using namespace std;  
    inline ll Min(ll a,ll b){return a>b?b:a;}  
    inline ll Max(ll a,ll b){return a>b?a:b;}  
      
    struct Point{
    	int x,y,dis;
    
    }p[N];
    bool cmp(Point a,Point b){
    	return a.dis<b.dis;
    }
    struct node{  
        int l,r;  
        ll sum;
    }tree[N*4];  
    
    void pushup(int id){
    	tree[id].sum = tree[R(id)].sum + tree[L(id)].sum;
    }
    
    void build(int l,int r,int id){
    	tree[id].l = l, tree[id].r = r;
    	tree[id].sum = r - l + 1;
    	if(l == r)return ;
    	int mid = Mid(l,r);
    	build( l, mid, L(id));		
    	build( mid+1, r, R(id));
    
    }
    
    void updata(int l, int r,int id){
    	if(l == tree[id].l && tree[id].r == r)
    	{ tree[id].sum = 0; return ;}
    
    	int mid=Mid(tree[id].l, tree[id].r);
    	if(r <= mid)updata(l, r, L(id));
    	else if(mid < l) updata(l, r, R(id));
    	else 
    	{
    		updata(l, mid, L(id));
    		updata(mid+1, r, R(id));
    	}
    	pushup(id);
    }
    int query(int l, int r, int id){
    	if(tree[id].sum==0)return 0;
    	if( tree[id].l == tree[id].r)return tree[id].sum;
    	int mid=Mid(tree[id].l, tree[id].r);
    
    	if(r <= mid)
    		return query(l, r, L(id));
    	if(mid < l )
    		return query(l, r, R(id));
    
    	return query(l, mid, L(id)) + query(mid+1, r, R(id));
    }
    
    int main(){
    	int n, m, i,temp;
    	while(~scanf("%d %d",&n,&m)){
    
    		for(i=1;i<=m;i++){
    			scanf("%d %d",&p[i].x,&p[i].y);
    			if(p[i].x>p[i].y)
    				temp=p[i].x, p[i].x=p[i].y, p[i].y=temp;
    			p[i].dis=p[i].y-p[i].x;
    		}
    
    		sort(p+1, p+m+1, cmp);
    
    		build(1,n,1);
    
    		int ans=0;
    		for(i=1;i<=m;i++){
    
    			ans=Max(ans, query(p[i].x, p[i].y, 1));
    			updata(p[i].x+1, p[i].y-1, 1);
    
    		}
    		ans=Max(ans, query(1,n,1));
    		printf("%d
    ",ans);
    
    	}
    	return 0;
    }
    
    /*
    6 3
    1 5
    1 4
    1 3
    
    ans:
    3
    */
    


  • 相关阅读:
    删除 Visual studio 生成后的临时文件
    C# 中的委托和事件(转)
    C#复制DataRow出现“该行已经属于此表”错误的解决办法(转)
    ini配置文件读取类
    c# wpf窗体前端显示问题
    注册系统热键类(原创)
    C# 窗体最小化的托盘/系统通知区域(转)
    php explode()返回值
    $_SERVER['SCRIPT_NAME']
    svn合并初次使用心得
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3343508.html
Copyright © 2011-2022 走看看