zoukankan      html  css  js  c++  java
  • [loj3272]汉堡肉

    当$kle 3$,这是一个经典的问题

    设所有矩形左下角横纵坐标的最大值为$(x_{1},y_{1})$,右上角横纵坐标的最小值为$(x_{2},y_{2})$,那么必然存在一组合法解满足其中一点为$(x_{1}/x_{2},y_{1}/y_{2})$,不断递归即可,时间复杂度为$o(4^{k}n)$

    当$k=4$,我们可以在四条边界线上各放一点来完成

    如果一个矩形完全覆盖了一条边(即覆盖了3或4条边,注意覆盖和完全覆盖不同),那么一定含有一个点,因此这类矩形的限制可以删掉

    对于剩下的矩形,其覆盖了1或2条边:对于覆盖1条边的,即每一个点有一个范围的限制;对于覆盖2条边的点,分类讨论:

    1.相邻的两条边,由于都是前缀/后缀,利用单调性维护

    2.相对的两条边,用线段树区间修改,维护出每一个点所对应的合法区间(求交)

    根据这个,枚举其中的一个点(离散),则其相邻的一条边上必然有一点选择其所限制的位置,再通过这两个点得到另外两点的限制,最后判断这两个点的限制能否满足(即这两个区间不为空且最相近时能否合法)

    时间复杂度为$o(nlog_{2}n+4^{k}n)$,即可通过

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define N 200005
      4 #define oo 0x3f3f3f3f
      5 #define pii pair<int,int>
      6 #define mp make_pair
      7 #define fi first
      8 #define se second
      9 #define L (k<<1)
     10 #define R (L+1)
     11 #define mid (l+r>>1)
     12 struct ji{
     13     int x1,y1,x2,y2;
     14 }a[N];
     15 vector<int>vx,vy,vv;
     16 vector<pii >ans;
     17 int n,m,vis[N],lim1[N],lim2[N],lim3[N],lim4[N];
     18 pii f[2][N<<2];
     19 void update(pii o,int k){
     20     ans.push_back(o);
     21     for(int i=1;i<=n;i++)
     22         if ((!vis[i])&&(a[i].x1<=o.fi)&&(o.fi<=a[i].x2)&&(a[i].y1<=o.se)&&(o.se<=a[i].y2))vis[i]=k;
     23 }
     24 void clear(int k){
     25     ans.pop_back();
     26     for(int i=1;i<=n;i++)
     27         if (vis[i]==k)vis[i]=0;
     28 }
     29 bool dfs(int k){
     30     if (k>m){
     31         for(int i=1;i<=n;i++)
     32             if (!vis[i])return 0;
     33         return 1;
     34     }
     35     ji o=ji{oo,oo,0,0};
     36     for(int i=1;i<=n;i++)
     37         if (!vis[i]){
     38             o.x1=min(o.x1,a[i].x2);
     39             o.y1=min(o.y1,a[i].y2);
     40             o.x2=max(o.x2,a[i].x1);
     41             o.y2=max(o.y2,a[i].y1);
     42         }
     43     update(mp(o.x1,o.y1),k);
     44     if (dfs(k+1))return 1;
     45     clear(k);
     46     update(mp(o.x1,o.y2),k);
     47     if (dfs(k+1))return 1;
     48     clear(k);
     49     update(mp(o.x2,o.y1),k);
     50     if (dfs(k+1))return 1;
     51     clear(k);
     52     update(mp(o.x2,o.y2),k);
     53     if (dfs(k+1))return 1;
     54     clear(k);
     55     return 0;
     56 }
     57 void org(vector<int>&v,int l,int r){
     58     sort(v.begin(),v.end());
     59     vv.clear();
     60     for(int i=0;i<v.size();i++)
     61         if ((l<=v[i])&&(v[i]<=r)&&((!vv.size())||(v[i]!=vv[vv.size()-1])))vv.push_back(v[i]);
     62     v=vv;
     63 }
     64 pii merge(pii x,pii y){
     65     return mp(max(x.fi,y.fi),min(x.se,y.se));
     66 }
     67 void build(int p,int k,int l,int r,int x){
     68     f[p][k]=mp(1,x);
     69     if (l==r)return;
     70     build(p,L,l,mid,x);
     71     build(p,R,mid+1,r,x);
     72 }
     73 void update(int p,int k,int l,int r,int x,int y,pii z){
     74     if ((l>y)||(x>r))return;
     75     if ((x<=l)&&(r<=y)){
     76         f[p][k]=merge(f[p][k],z);
     77         return;
     78     }
     79     update(p,L,l,mid,x,y,z);
     80     update(p,R,mid+1,r,x,y,z);
     81 }
     82 pii query(int p,int k,int l,int r,int x){
     83     if (l==r)return f[p][k];
     84     if (x<=mid)return merge(f[p][k],query(p,L,l,mid,x));
     85     return merge(f[p][k],query(p,R,mid+1,r,x));
     86 }
     87 int main(){
     88     scanf("%d%d",&n,&m);
     89     for(int i=1;i<=n;i++)scanf("%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
     90     if (dfs(1)){
     91         for(int i=0;i<m;i++)printf("%d %d
    ",ans[i].fi,ans[i].se);
     92         return 0;
     93     }
     94     ji o=ji{oo,oo,0,0};
     95     for(int i=1;i<=n;i++){
     96         o.x1=min(o.x1,a[i].x2);
     97         o.y1=min(o.y1,a[i].y2);
     98         o.x2=max(o.x2,a[i].x1);
     99         o.y2=max(o.y2,a[i].y1);
    100     }
    101     for(int i=1;i<=n;i++){
    102         vx.push_back(a[i].x1);
    103         vy.push_back(a[i].y1);
    104         vx.push_back(a[i].x2);
    105         vy.push_back(a[i].y2);
    106     }
    107     org(vx,o.x1,o.x2);
    108     org(vy,o.y1,o.y2);
    109     int nx=vx.size(),ny=vy.size();
    110     build(0,1,1,ny,nx);
    111     build(1,1,1,nx,ny);
    112     int l1=0,l2=0;
    113     for(int i=1;i<=n;i++){
    114         a[i].x1=lower_bound(vx.begin(),vx.end(),a[i].x1)-vx.begin()+1;
    115         a[i].x1=min(a[i].x1,nx);
    116         a[i].y1=lower_bound(vy.begin(),vy.end(),a[i].y1)-vy.begin()+1;
    117         a[i].y1=min(a[i].y1,ny);
    118         a[i].x2=lower_bound(vx.begin(),vx.end(),a[i].x2)-vx.begin()+1;
    119         a[i].x2=min(a[i].x2,nx);
    120         a[i].y2=lower_bound(vy.begin(),vy.end(),a[i].y2)-vy.begin()+1;
    121         a[i].y2=min(a[i].y2,ny);
    122     }
    123     for(int i=1;i<=ny;i++)lim1[i]=lim2[i]=nx;
    124     for(int i=1;i<=nx;i++)lim3[i]=ny;
    125     for(int i=1;i<=nx;i++)lim4[i]=1;
    126     for(int i=1;i<=n;i++){
    127         if ((a[i].x1==1)&&(a[i].x2==nx)){
    128             if ((a[i].y1==1)||(a[i].y2==ny))continue;
    129             update(0,1,1,ny,1,a[i].y1-1,mp(a[i].y1,a[i].y2));
    130             update(0,1,1,ny,a[i].y2+1,ny,mp(a[i].y1,a[i].y2));
    131             continue;
    132         }
    133         if ((a[i].y1==1)&&(a[i].y2==ny)){
    134             if ((a[i].x1==1)||(a[i].x2==nx))continue;
    135             update(1,1,1,nx,1,a[i].x1-1,mp(a[i].x1,a[i].x2));
    136             update(1,1,1,nx,a[i].x2+1,nx,mp(a[i].x1,a[i].x2));
    137             continue;
    138         }
    139         if (a[i].x1==1){
    140             if (a[i].y1==1)lim1[a[i].y2+1]=min(lim1[a[i].y2+1],a[i].x2);
    141             if (a[i].y2==ny)lim2[a[i].y1-1]=min(lim2[a[i].y1-1],a[i].x2);
    142             if ((a[i].y1!=1)&&(a[i].y2!=ny)){
    143                 update(0,1,1,ny,1,a[i].y1-1,mp(nx,1));
    144                 update(0,1,1,ny,a[i].y2+1,ny,mp(nx,1));
    145             }
    146             continue;
    147         }
    148         if (a[i].x2==nx){
    149             if (a[i].y1==1)lim3[a[i].x1-1]=min(lim3[a[i].x1-1],a[i].y2);
    150             if (a[i].y2==ny)lim4[a[i].x1-1]=max(lim4[a[i].x1-1],a[i].y1);
    151             if ((a[i].y1!=1)&&(a[i].y2!=ny))update(0,1,1,ny,1,ny,mp(a[i].y1,a[i].y2));
    152             continue;
    153         }
    154         if (a[i].y1==1){
    155             l1=max(l1,a[i].x1);
    156             lim1[1]=min(lim1[1],a[i].x2);
    157         }
    158         if (a[i].y1==ny){
    159             l2=max(l2,a[i].x1);
    160             lim2[ny]=min(lim2[ny],a[i].x2);
    161         }
    162     }
    163     for(int i=2;i<=ny;i++)lim1[i]=min(lim1[i],lim1[i-1]);
    164     for(int i=ny-1;i;i--)lim2[i]=min(lim2[i],lim2[i+1]);
    165     for(int i=nx-1;i;i--)lim3[i]=min(lim3[i],lim3[i+1]);
    166     for(int i=nx-1;i;i--)lim4[i]=max(lim4[i],lim4[i+1]);
    167     for(int i=1;i<=ny;i++){
    168         if (!lim1[i])continue;
    169         pii o1=query(0,1,1,ny,i),o2=query(1,1,1,nx,lim1[i]);
    170         o1.se=min(o1.se,lim3[lim1[i]]);
    171         o2.se=min(o2.se,lim2[i]);
    172         if ((o1.fi>o1.se)||(o2.fi>o2.se))continue;
    173         if (o1.se>=lim4[o2.se]){
    174             printf("%d %d
    ",vx[0],vy[i-1]);
    175             printf("%d %d
    ",vx[lim1[i]-1],vy[0]);
    176             printf("%d %d
    ",vx[nx-1],vy[o1.se-1]);
    177             printf("%d %d
    ",vx[o2.se-1],vy[ny-1]);
    178             return 0;
    179         }
    180     }
    181     for(int i=1;i<=ny;i++){
    182         if (!lim2[i])continue;
    183         pii o1=query(0,1,1,ny,i),o2=query(1,1,1,nx,lim2[i]);
    184         o1.fi=max(o1.fi,lim4[lim2[i]]);
    185         o2.se=min(o2.se,lim1[i]);
    186         if ((o1.fi>o1.se)||(o2.fi>o2.se))continue;
    187         if (o1.fi<=lim3[o2.se]){
    188             printf("%d %d
    ",vx[0],vy[i-1]);
    189             printf("%d %d
    ",vx[lim2[i]-1],vy[ny-1]);
    190             printf("%d %d
    ",vx[nx-1],vy[o1.fi-1]);
    191             printf("%d %d
    ",vx[o2.se-1],vy[0]);
    192             return 0;
    193         }
    194     }
    195     return 0;
    196 }
    View Code
  • 相关阅读:
    像画笔一样慢慢画出Path的三种方法(补充第四种)
    占位符行为 PlaceHolderBehavior 的实现以及使用
    WPF实现物理效果 拉一个小球
    WPF实现Twitter按钮效果
    WPF自适应可关闭的TabControl 类似浏览器的标签页
    WPF仿百度Echarts人口迁移图
    WPF绘制简单常用的Path
    51Nod 1534 棋子游戏
    数论基础
    Buy a Ticket
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13869618.html
Copyright © 2011-2022 走看看