题意很好理解,关键是要抽象成一棵二叉树,每一个空白矩形是一个叶子节点,每次插入一条线段都把一个空白矩形分为两个矩形,也就是要产生两个节点,所以总的节点的数目是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 }