HDU4429

一道水题调了两天,被自己蠢哭

题解:

由题意明显有一个矩形和他分割后的矩形形成类似二叉树中父亲与孩子的关系,根据图把树建出来暴力LCA即可

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int N=2005;

int n,q,cnt;
int xl[N],yl[N],xr[N],yr[N];
int fa[N],dep[N],siz[N];
vector<int> son[N];

inline void Insert_point(int t,int x1,int y1,int x2,int y2)
 {
     cnt++;
     fa[cnt]=t;
     dep[cnt]=dep[t]+1;
     son[t].push_back(cnt);
     xl[cnt]=xl[t]; yl[cnt]=yl[t];
     xr[cnt]=x2; yr[cnt]=y2;
     cnt++;
     fa[cnt]=t;
     dep[cnt]=dep[t]+1;
     son[t].push_back(cnt);
     xl[cnt]=x1; yl[cnt]=y1;
     xr[cnt]=xr[t]; yr[cnt]=yr[t];
 }

void dfs(int x)
 {
     if (son[x].empty()) return (void) (siz[x]=1);
     siz[x]=0;
      for (int i=0;i<son[x].size();i++)
       {
            dfs(son[x][i]);
            siz[x]+=siz[son[x][i]];
      }
 }

inline int find(int x,int y)
 {
     for (int i=1;i<=cnt;i++)
      if (son[i].empty())
       if (xl[i]<=x&&xr[i]>=x)
       if (yl[i]<=y&&yr[i]>=y)
        return i;
 }

inline int Get_LCA(int u,int v)
 {
     while (u!=v)
     {
         if (dep[u]<dep[v]) swap(u,v);
         u=fa[u];
      }
     return u;
 }

int main()
 {
     while (~scanf("%d%d%d%d",&xl[1],&yl[1],&xr[1],&yr[1]))
      {
         scanf("%d%d",&n,&q);
         cnt=1;
         for (int i=1;i<=n;i++)
          {
             int x1,y1,x2,y2;
             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
             if (x1>x2) swap(x1,x2);
             if (y1>y2) swap(y1,y2);
             int t=find((x1+x2)/2,(y1+y2)/2);
             Insert_point(t,x1,y1,x2,y2);
          }
         dfs(1);
         while (q--)
          {
             int x1,y1,x2,y2;
             scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
             int u=find(x1,y1);
             int v=find(x2,y2);
             printf("%d\n",n+2-siz[Get_LCA(u,v)]);
          }
         memset(fa,0,sizeof(fa));
         memset(siz,0,sizeof(siz));
         memset(dep,0,sizeof(dep));
         for (int i=1;i<=cnt;i++)
          vector<int>().swap(son[i]);
      }
     return 0;
 }


我是怎么把自己蠢哭的QAQ:

卡常习惯/2使用>>1,结果这题有负数……



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值