zoukankan      html  css  js  c++  java
  • ZOJ 3664Split the Rectangle解题报告

    题意很好理解,关键是要抽象成一棵二叉树,每一个空白矩形是一个叶子节点,每次插入一条线段都把一个空白矩形分为两个矩形,也就是要产生两个节点,所以总的节点的数目是N*2+1,然后要标记线段的方向和矩形被分割的方向,分情况判断在左孩子还是右孩子插入节点,RMQ判断最近公共祖先,求的是去掉公共祖先的子树剩下多少叶子节点,插入实在是太费劲了,麻烦啊,还因为一个细节错了两次

    View Code
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #define N 3005
      6 #define min(a,b) ((a)<(b)?(a):(b))
      7 #define max(a,b) ((a)>(b)?(a):(b))
      8 using namespace std;
      9 int son[N][2],pos[N];//son数组存储其子节点,pos存储其子树中有多少叶子节点
     10 bool isleaf[N];//记录是否是叶子节点
     11 int dp[2*N][15];
     12 struct rectangle
     13 {
     14     int xl,yl;
     15     int xr,yr;
     16     int flag;
     17 };
     18 struct segment
     19 {
     20     int x1,y1;
     21     int x2,y2;
     22     int flag;
     23 };
     24 struct point
     25 {
     26     int x,y;
     27 };
     28 rectangle rec[N];
     29 int cnt;
     30 int lis[2*N],deep[2*N],firs[2*N],ti;//RMQ找LCA要用到的部分
     31 void init()
     32 {
     33     memset(son,-1,sizeof(son));
     34     memset(pos,0,sizeof(pos));
     35     memset(isleaf,true,sizeof(isleaf));
     36     cnt=1;
     37     ti=1;
     38     memset(firs,-1,sizeof(firs));
     39     memset(deep,-1,sizeof(deep));
     40 }
     41 void insert(segment seg,int id)//插入线段
     42 {
     43     if(isleaf[id])//是叶子节点直接插入
     44     {
     45         rec[id].flag=seg.flag;
     46         if(seg.flag==0)
     47         {
     48             rec[cnt].xl=rec[id].xl;
     49             rec[cnt].yl=rec[id].yl;
     50             rec[cnt].xr=rec[id].xr;
     51             rec[cnt].yr=seg.y1;
     52             son[id][0]=cnt;
     53             cnt++;
     54             rec[cnt].xl=rec[id].xl;
     55             rec[cnt].yl=seg.y1;
     56             rec[cnt].xr=rec[id].xr;
     57             rec[cnt].yr=rec[id].yr;
     58             son[id][1]=cnt;
     59             cnt++;
     60         }
     61         else
     62         {
     63             rec[cnt].xl=rec[id].xl;
     64             rec[cnt].yl=rec[id].yl;
     65             rec[cnt].xr=seg.x1;
     66             rec[cnt].yr=rec[id].yr;
     67             son[id][0]=cnt;
     68             cnt++;
     69             rec[cnt].xl=seg.x1;
     70             rec[cnt].yl=rec[id].yl;
     71             rec[cnt].xr=rec[id].xr;
     72             rec[cnt].yr=rec[id].yr;
     73             son[id][1]=cnt;
     74             cnt++;
     75         }
     76         isleaf[id]=false;
     77         return;
     78     }
     79     else
     80     {
     81         if(rec[id].flag==0)
     82         {
     83             if(seg.flag==0)
     84             {
     85                 if(seg.y1>=rec[son[id][0]].yl&&seg.y1<=rec[son[id][0]].yr)
     86                     insert(seg,son[id][0]);
     87                 else
     88                     insert(seg,son[id][1]);
     89             }
     90             else
     91             {
     92                 if(max(seg.y1,seg.y2)<=rec[son[id][0]].yr&&min(seg.y1,seg.y2)>=rec[son[id][0]].yl)
     93                     insert(seg,son[id][0]);
     94                 else
     95                     insert(seg,son[id][1]);
     96             }
     97         }
     98         else
     99         {
    100             if(seg.flag==0)
    101             {
    102                 if(min(seg.x1,seg.x2)>=rec[son[id][0]].xl&&max(seg.x1,seg.x2)<=rec[son[id][0]].xr)
    103                     insert(seg,son[id][0]);
    104                 else
    105                     insert(seg,son[id][1]);
    106             }
    107             else
    108             {
    109                 if(seg.x1>=rec[son[id][0]].xl&&seg.x1<=rec[son[id][0]].xr)
    110                     insert(seg,son[id][0]);
    111                 else
    112                     insert(seg,son[id][1]);
    113             }
    114         }
    115     }
    116 }
    117 void makermq()
    118 {
    119     int i,j;
    120     for(i=1;i<ti;i++)
    121         dp[i][0]=i;
    122     for(j=1;(1<<j)<ti;j++)
    123         for(i=1;i+(1<<j)-1<ti;i++)
    124         {
    125             if(deep[dp[i][j-1]]<deep[dp[i+(1<<(j-1))][j-1]])
    126                 dp[i][j]=dp[i][j-1];
    127             else
    128                 dp[i][j]=dp[i+(1<<(j-1))][j-1];
    129         }
    130 }
    131 int rmq(int s,int e)
    132 {
    133     s=firs[s];
    134     e=firs[e];
    135     int k=(int)(log((e-s+1)*1.0)/log(2.0));
    136     int ans=deep[dp[s][k]]<deep[dp[e-(1<<k)+1][k]]?dp[s][k]:dp[e-(1<<k)+1][k];
    137     return lis[ans];
    138 }
    139 void dfs(int u,int de)
    140 {
    141     deep[ti]=de;
    142     lis[ti]=u;
    143     firs[u]=ti;
    144     ti++;
    145     if(isleaf[u])
    146     {
    147         pos[u]=1;
    148         return;
    149     }
    150     int i;
    151     for(i=0;i<=1;i++)
    152     {
    153         dfs(son[u][i],de+1);
    154         lis[ti]=u;
    155         deep[ti]=de;
    156         ti++;
    157     }
    158     pos[u]=pos[son[u][0]]+pos[son[u][1]];
    159 }
    160 int find(point p,int id)//查找点所在的叶子节点
    161 {
    162     if(isleaf[id])
    163         return id;
    164     if(p.x>=rec[son[id][0]].xl&&p.x<=rec[son[id][0]].xr&&p.y>=rec[son[id][0]].yl&&p.y<=rec[son[id][0]].yr)
    165         return find(p,son[id][0]);
    166     return find(p,son[id][1]);
    167 }
    168 int main()
    169 {
    170     int n,q,i,j,k;
    171     int r1,r2,anc;
    172     segment seg;
    173     point p1,p2;
    174     while(scanf("%d%d%d%d",&rec[0].xl,&rec[0].yl,&rec[0].xr,&rec[0].yr)!=EOF)
    175     {
    176         init();
    177         scanf("%d%d",&n,&q);
    178         for(i=0;i<n;i++)
    179         {
    180             scanf("%d%d%d%d",&seg.x1,&seg.y1,&seg.x2,&seg.y2);
    181             if(seg.x1==seg.x2)
    182                 seg.flag=1;
    183             else
    184                 seg.flag=0;
    185             insert(seg,0);
    186         }
    187         dfs(0,1);
    188         makermq();
    189         for(i=0;i<q;i++)
    190         {
    191             scanf("%d%d%d%d",&p1.x,&p1.y,&p2.x,&p2.y);
    192             r1=find(p1,0);
    193             r2=find(p2,0);
    194             if(firs[r1]>firs[r2])
    195             {
    196                 r1^=r2;
    197                 r2^=r1;
    198                 r1^=r2;
    199             }
    200             anc=rmq(r1,r2);
    201             printf("%d\n",n+2-pos[anc]);
    202         }
    203     }
    204     return 0;
    205 }
  • 相关阅读:
    Python爬虫技术--基础篇--函数式编程(上篇)
    Python爬虫技术--基础篇--Python高级特性
    Python爬虫技术--基础篇--函数(下篇)
    Python爬虫技术--基础篇--函数(上篇)
    Python爬虫技术--基础篇--字典和集合
    Python爬虫技术--基础篇--列表和元组
    1013 数素数
    1012 数字分类
    1010 一元多项式求导
    1011 A+B 和 C
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2728660.html
Copyright © 2011-2022 走看看