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 }
原文地址:https://www.cnblogs.com/caozhenhai/p/2728660.html