Description

给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。

Input

第一行一个整数n(n <= 50000),代表有n个点。点1,2,3,…,n是凸多边形上是顺时针排布的。

接下来n-3行,每行两个整数(x,y),代表(x,y)之间有一条剖分边。

接下来是一个整数q(q <= 100000),代表有q组询问。

接下来q行是两个整数(a,b)。

Output

输出q行,每行一个整数代表最少边数。

运用分治的思想,每一次选择一条剖分边,使得凸多边形分成尽量平均的两部分。使用bfs得出该条边的两个端点到各个顶点的最短路,对所有的询问在两个端点处进行拼凑并更新答案。然后对两部分的信息分别划开,进行下一层的分治。

(每次分治完,点数会比原来多2,所以空间要开三倍。)

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
const int N=3e5+;
const int inf=0x3f3f3f3f;
int n,m,cnt,x,y,t,tmp;
int first[N],ans[N],id[N];
int qq[N],disx[N],disy[N],q1[N],q2[N];
bool ok[N];
struct node{int x,y,id;}l[N],q[N],h1[N],h2[N];
struct edge{int to,next;}e[N<<];
int read()
{
int x=,f=;char c=getchar();
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
int find(int l,int r,int x){return lower_bound(id+l,id+r+,x)-id;}
void bfs(int S,int pl,int pr,int *dis)
{
int head=,tail=;
for(int i=pl;i<=pr;i++)dis[id[i]]=inf;
qq[tail++]=S;dis[S]=;
while(head!=tail)
{
int u=qq[head++];
for(int i=first[u];i;i=e[i].next)
{
int to=e[i].to;
if(!ok[to])continue;
if(dis[to]==inf)dis[to]=dis[u]+,qq[tail++]=to;
}
}
}
void work(int dl,int dr,int pl,int pr,int ql,int qr)
{
if(dl>dr||pl>pr||ql>qr)return;
int mn=inf,mnid=;
for(int i=dl;i<=dr;i++)
{
x=find(pl,pr,l[i].x);y=find(pl,pr,l[i].y);
if(x>y)swap(x,y);
tmp=max(y-x,x-y+pr-pl+);
if(tmp<mn)mn=tmp,mnid=i;
}
for(int i=pl;i<=pr;i++)ok[id[i]]=true;
bfs(l[mnid].x,pl,pr,disx);
bfs(l[mnid].y,pl,pr,disy);
for(int i=pl;i<=pr;i++)ok[id[i]]=false;
int t1=,t2=,t3=,t4=,t5=,t6=;
for(int i=ql;i<=qr;i++)
{
x=q[i].x;y=q[i].y;t=q[i].id;
if(x==l[mnid].x&&y==l[mnid].y){ans[t]=;continue;}
ans[t]=min(ans[t],disx[x]+disx[y]);
ans[t]=min(ans[t],disy[x]+disy[y]);
ans[t]=min(ans[t],disx[x]+disy[y]+);
ans[t]=min(ans[t],disy[x]+disx[y]+);
if(q[i].x>l[mnid].x&&q[i].y<l[mnid].y)h1[++t1]=q[i];
else if((q[i].x<l[mnid].x||q[i].x>l[mnid].y)&&
(q[i].y<l[mnid].x||q[i].y>l[mnid].y))h2[++t2]=q[i];
}
for(int i=;i<=t1;i++)q[ql+i-]=h1[i];
for(int i=;i<=t2;i++)q[ql+t1+i-]=h2[i];
for(int i=pl;i<=pr;i++)
{
if(id[i]>=l[mnid].x&&id[i]<=l[mnid].y)q1[++t3]=id[i];
if(id[i]<=l[mnid].x||id[i]>=l[mnid].y)q2[++t4]=id[i];
}
for(int i=;i<=t3;i++)id[pl+i-]=q1[i];
for(int i=;i<=t4;i++)id[pl+t3+i-]=q2[i];
for(int i=dl;i<=dr;i++)
{
if(i==mnid)continue;
if(l[i].x>=l[mnid].x&&l[i].y<=l[mnid].y)h1[++t5]=l[i];
else h2[++t6]=l[i];
}
for(int i=;i<=t5;i++)l[dl+i-]=h1[i];
for(int i=;i<=t6;i++)l[dl+t5+i-]=h2[i];
work(dl+t5,dl+t5+t6-,pl+t3,pl+t3+t4-,ql+t1,ql+t1+t2-);
work(dl,dl+t5-,pl,pl+t3-,ql,ql+t1-);
}
int main()
{
n=read();
for(int i=;i<=n-;i++)
{
l[i].x=read();l[i].y=read();
ins(l[i].x,l[i].y);ins(l[i].y,l[i].x);
if(l[i].x>l[i].y)swap(l[i].x,l[i].y);
}
for(int i=;i<n;i++)ins(i,i+),ins(i+,i);
ins(,n);ins(n,);
m=read();
for(int i=;i<=m;i++)
{
q[i].x=read();q[i].y=read();q[i].id=i;
if(q[i].x>q[i].y)swap(q[i].x,q[i].y);
ans[i]=min(q[i].y-q[i].x,q[i].x-q[i].y+n);
}
for(int i=;i<=n;i++)id[i]=i;
work(,n-,,n,,m);
for(int i=;i<=m;i++)printf("%d\n",ans[i]);
return ;
}

【bzoj 4449】[Neerc2015]Distance on Triangulation的更多相关文章

  1. 【BZOJ 4449】[Neerc2015]Distance on Triangulation 多边形分治结构

    这题好神啊……正解方向是分治,据我所知的分治方法有:I.离线后直接对多边形以及所有的询问进行分治 II.建立多边形的分治结构(对于三角形来说类似线段树,对于对角线来说类似平衡树),然后每次在这个分治结 ...

  2. 一本通1619【例 1】Prime Distance

    1619: [例 1]Prime Distance 题目描述 原题来自:Waterloo local,题面详见 POJ 2689 给定两个整数 L,R,求闭区间 [L,R] 中相邻两个质数差值最小的数 ...

  3. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  4. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  5. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  6. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  7. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  8. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  9. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

随机推荐

  1. NTFS权限和共享权限的区别

    共享权限 共享权限有三种:完全控制.更改.读取 共持本地安全性.换句话说,他在同一台计算机上以不同用户名登录,对硬盘上同一文件夹可以有不同的访问权限. 注意:NTFS权限对从网络访问和本机登录的用户都 ...

  2. kali权限提升之本地提权

    kali权限提升之本地提权 系统账号之间权限隔离 操作系统的安全基础 用户空间 内核空间 系统账号: 用户账号登陆时候获取权限令牌 服务账号无需用户登录已在后台启动服务 windows用户全权限划分: ...

  3. 标识符and数据类型

    一,标识符 1.标识符用来给类,变量,包,方法等起名字的. 2.只能由字符,下滑线,美元符组成:这里的字符有大小写字母,中文字符,数字字符,但是符号只能有两个下划线和美元符. 3.不能由数字开头. 4 ...

  4. C/C++中容器vector用法

    C++中数组非常坑,有没有相似Python中list的数据类型呢?相似的就是vector!vector 是同一种类型的对象的集合,每一个对象都有一个对应的整数索引值. 和 string 对象一样.标准 ...

  5. jQuery的siblings方法

    在使用siblings方法的时候,发现p标签,选中是没有效果的 解决:在w3c中测试也发现是没有效果的,也没有其他的特殊说明,于是度娘之后发现: siblings()获取的是当前标签元素的所有同辈的标 ...

  6. FreeHttp1.1升级说明

    一.升级方法 下载新版本插件 https://files.cnblogs.com/files/lulianqi/FreeHttp1.1.zip  或 http://lulianqi.com/file/ ...

  7. 19 款仿 Bootstrap 后台管理主题免费下载

    声明: 1. 本篇文章提到的仿 Bootstrap 风格的主题,是基于 jQuery 的 ASP.NET MVC 控件库的主题. 2. FineUIMvc(基础版)完全免费,可以用于商业项目. 目录 ...

  8. 02-MySQL基础

    MySQL基础 1.存储引擎 1.1MyISAM MySQL5.5以及之前默认存储引擎MyISAM 如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性.并发性要求不高,那么 ...

  9. 腾讯通信云服务端使用心得,腾讯云IM

    腾讯通信云服务端使用心得 1.腾讯通信服务入口并创建应用 方便使用保留url地址 :   https://cloud.tencent.com/product/im 注册账号腾讯云账号->通过审核 ...

  10. Photoshop给河边婚片加上唯美的霞光

    <点小图查看大图> 最终效果 1.打开原图素材大图,按Ctrl + Alt + 2 调出高光选区,按Ctrl + Shift + I 反选得到暗部选区,然后创建曲线调整图层,对RGB.红. ...