• Pizza Cutter (树状数组+模拟+离散)


    Grandpa Giuseppe won a professional pizza cutter, the kind of type reel and, to celebrate, baked a rectangle pizza to his grandchildren! He always sliced his pizzas into pieces by making cuts over continuous lines, not necessarily rectilinear, of two types: some begin at the left edge of the pizza, follow continuously to the right and end up in the right edge; other start on lower edge, follow continuously up and end up on the top edge. But Grandpa Giuseppe always followed a property: two cuts of the same type would never intersect. Here is an example with 4 cuts, two of each type, in the left part of the figure, which divide the pizza in 9 pieces.
    
    
    It turns out that Grandpa Giuseppe simply loves geometry, topology, combinatorics and stuff; so, he decided to show to his grandchildren who could get more pieces with the same number of cuts if cross cuts of the same type were allowed. The right part of the figure shows, for example, that if the two cuts of the type that go from left to right could intercept, the pizza would be divided into 10 pieces.
    
    Grandpa Giuseppe ruled out the property, but will not make random cuts. In addition to being one of the two types, they will comply with the following restrictions:
    
    Two cuts have at most one intersection point and, if they have, it is because the cuts cross each other at that point;
    Three cuts do not intersect in a single point;
    Two cuts do not intersect at the border of the pizza;
    A cut does not intercept a pizza corner.
    Given the start and end points of each cut, your program should compute the number of resulting pieces from the cuts of Grandfather Giuseppe.
    
    Input
    The first line of the input contains two integers XX and YY, (1 \leq X, Y \leq 10^91≤X,Y≤10 
    9
     ), representing the coordinates (X, Y)(X,Y) of the upper-right corner of the pizza. The lower left corner has always coordinates (0, 0)(0,0). The second line contains two integers HH and VV, (1 \leq H, V \leq 10^51≤H,V≤10 
    5
     ), indicating, respectively, the number of cuts ranging from left to right and the number of cuts ranging from bottom to top. Each of the following lines HH contains two integers Y_1Y 
    1
    ​
      and Y_2Y 
    2
    ​
     , a cut that intercepts the left side with y-coordinate Y_1Y 
    1
    ​
      and the right side at y-coordinate Y_2Y 
    2
    ​
     . Each of the following VV lines contains two integers X_1X 
    1
    ​
      and X_2X 
    2
    ​
     , a cut that intercept the bottom side at x-coordinate X_1X 
    1
    ​
      and the upper side at x-coordinate X_2X 
    2
    ​
     .
    
    Sample 1
    Inputcopy    Outputcopy
    3 4
    3 2
    1 2
    2 1
    3 3
    1 1
    2 2
    13
    Sample 2
    Inputcopy    Outputcopy
    5 5
    3 3
    2 1
    3 2
    1 3
    3 4
    4 3
    2 2
    19
    Sample 3
    Inputcopy    Outputcopy
    10000 10000
    1 2
    321 3455
    10 2347
    543 8765
    View problem

    思路:

    更具题目可以得到公式: ans=1ll*(n+1)*(m+1)+ 横向的交点数+纵向的交点数;

    离散后 利用 树状数组求 交点数,把x 从小到大排序,依次看 区间 y-n 之间 有几个数了。在把y这个点进行更新(数目+1)

    #include <bits/stdc++.h>
    using namespace std;
    #define ri register int
    #define  M 200010
    
    template <class G >  void read(G &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
    
    struct dain{
        int x,y,id;
        bool operator <(const dain t)const 
        {
            if(x==t.x) return y<t.y ;
            return x<t.x;
        }
    }p1[M];
    struct din{
        int x,y,id;
        bool operator <(const din t)const 
        {
            if(y==t.y) return x<t.x; 
            return y<t.y;
        }
    }p2[M];
    
    struct dian{
        long long  x,y;
        bool operator <(const dian &t)const 
        {
            return x<t.x;
        }
    }p[M];
    int T;
    int tr[M];
    int qu(int a)
    {
        int ans=0;
        while(a)
        {
            ans+=tr[a];
            a-=a&(-a);
        }
        return ans;
    }
    void add(int a,int n)
    {
        while(a<=n)
        {
            tr[a]++;
            a+=a&(-a);
        }
    }
    long long  n,m;
    int main(){
        
        
        read(n);read(m);
        read(n);read(m);
        long long ans=1ll*(n+1)*(m+1);
        for(ri i=1;i<=n;i++)
        {
            read(p1[i].x);read(p1[i].y);
            p2[i].x=p1[i].x;p2[i].y=p1[i].y;
            p1[i].id=i;p2[i].id=i;
        }
        sort(p1+1,p1+1+n);sort(p2+1,p2+1+n);
        for(ri i=1;i<=n;i++)
        {
            p[p1[i].id].x=i;
            p[p2[i].id].y=i;
        }
        sort(p+1,p+1+n);
        for(ri i=1;i<=n;i++)
        {
            ans+=qu(n)-qu(p[i].y-1);
            add(p[i].y,n);
        }
        for(ri i=1;i<=n;i++) tr[i]=0;
        for(ri i=1;i<=m;i++)
        {
            read(p1[i].x);read(p1[i].y);
            p2[i].x=p1[i].x;p2[i].y=p1[i].y;
            p1[i].id=i;p2[i].id=i;
        }
        sort(p1+1,p1+1+m);sort(p2+1,p2+1+m);
        for(ri i=1;i<=m;i++)
        {
            p[p1[i].id].x=i;
            p[p2[i].id].y=i;
        }
        sort(p+1,p+1+m);
        for(ri i=1;i<=m;i++)
        {
    
            ans+=qu(m)-qu(p[i].y-1);
            add(p[i].y,m);
        }
        printf("%lld",ans);
        return 0;
    
        
    }
    View Code
  • 相关阅读:
    cocos2d JS 在 JavaScript 中,怎样把一个对象转化成 JSON 字符串?
    cocos2d-x 暂停/恢复 与场景相关(SceneGraph类型)的监听器
    cocos2d CCNode类(节点属性大全)
    cocos2d-x 错误异常抛出捕获和崩溃拦截
    cocos2d JS 鼠标响应事件
    cocos2d JS 创建实现换行功能的聊天文本 testLable
    cocos2d JS 自定义事件分发器(接收与传递数据) eventManager
    cocos2d JS 监听键盘触摸响应事件(cc.EventListener.KEYBOARD)
    cocos2d JS touch(触摸监听)-快速添加事件监听器到管理器
    cocos2dx C++ imageView(图片/九宫格)相关属性大全
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/16109166.html
Copyright © 2020-2023  润新知