bzoj 4449: [Neerc2015]Distance on Triangulation
Description
给定一个凸n边形,以及它的三角剖分。再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b。
Input
第一行一个整数n(n <= 50000),代表有n个点。点1,2,3,…,n是凸多边形上是顺时针排布的。
Output
#include<bits/stdc++.h>
char buf[],*ptr=buf+;
int G(){
if(ptr-buf==)fread(ptr=buf,,,stdin);
return *ptr++;
}
int _(){
int x=;
if(ptr-buf<){
while(*ptr<)++ptr;
while(*ptr>)x=x*+*ptr++-;
}else{
int c=G();
while(c<)c=G();
while(c>)x=x*+c-,c=G();
}
return x;
}
const int N=,inf=0x3f3f3f3f,P=;
int n,qp,idp=;
int deg[N],q[N],ql=,qr=,as[N];
std::vector<int>e0[N],ee[N];
struct Q{int w,id;};
std::vector<Q>qq[N];
Q*qs[N][];
int sz[N],*lr[N][],*et[N][];
int p3[N][];
void ae(int a,int b){
++deg[b];++deg[a];
e0[a].push_back(b);
e0[b].push_back(a);
} struct hash_map{
int h[P][];
int*operator()(int a,int b){
if(a>b)std::swap(a,b);
int w=(a*+b*)%P;
while(h[w][]){
if(h[w][]==a&&h[w][]==b)return h[w]+;
if((w+=)>=P)w-=P;
}
h[w][]=a,h[w][]=b;
return h[w]+;
}
}h1,h2;
void chk(int a,int b){
if(a>b)std::swap(a,b);
if(a==&&b==n||a+==b)return;
int*w=h1(a,b);
if(w[]){
int x=idp,y=w[];
ee[x].push_back(y);
ee[y].push_back(x);
int*c=h2(x,y);
c[]=a;c[]=b;
}else w[]=idp;
}
int ss[N][],sp,tk=,ed[N],ed2[N];
int ps[N],pp=;
void ins(int a){
for(int t=;t<;++t){
int w=p3[a][t];
if(ed2[w]!=tk)ed2[ps[pp++]=w]=tk;
}
}
void f2(int w,int pa){
sz[w]=;
ed[w]=tk;
ss[sp][]=w,ss[sp++][]=pa;
for(int*l=lr[w][],*r=lr[w][];l!=r;++l){
int u=*l;
if(u==pa)continue;
f2(u,w);
sz[w]+=sz[u];
}
}
void dele(int a,int b){
for(int*l=lr[a][],*r=lr[a][];l!=r;++l)if(*l==b){
*l=*--lr[a][];
return;
}
}
int min(int a,int b){return a<b?a:b;}
void mins(int&a,int b){if(a>b)a=b;}
int d1[N],d2[N],dd1[N],dd2[N],dk=;
bool qd[N];
void bfs(int w,int*d,int*dd){
ql=qr=;
dd[q[++qr]=w]=dk,d[w]=;
while(ql!=qr){
w=q[++ql];
for(int*l=et[w][],*r=et[w][];l!=r;++l){
int u=*l;
if(ed2[u]==tk&&dd[u]!=dk)dd[q[++qr]=u]=dk,d[u]=d[w]+;
}
}
}
void f1(int w){
++tk;
pp=;
sp=;
f2(w,);
int SZ=sz[w];
if(SZ>){
int mx=,p1=w,p2=;
for(int i=;i<sp;++i){
int u=ss[i][],mv=min(sz[u],SZ-sz[u]);
if(mv>mx)mx=mv,p1=u,p2=ss[i][];
ins(u);
}
dele(p1,p2);
dele(p2,p1);
int*ns=h2(p1,p2);
++dk;
bfs(ns[],d1,dd1);bfs(ns[],d2,dd2);
for(int i=;i<pp;++i){
int u=ps[i];
int d1u=d1[u];
int d2u=d2[u];
for(Q*l=qs[u][],*r=qs[u][];l!=r;++l){
int v=l->w;
if(qd[v])*l--=*(qs[u][]=--r);
else if(ed2[v]==tk){
int d1v=d1[v];
int d2v=d2[v];
mins(as[l->id],min(min(d1u+d1v,d2u+d2v),min(d1u+d2v+,d2u+d1v+)));
}
}
}
qd[ns[]]=qd[ns[]]=;
for(int d=;d<;++d)qs[ns[d]][]=qs[ns[d]][];
f1(p1);f1(p2);
}
}
int main(){
n=_();
for(int i=,a,b;i<=n-;++i){
a=_();b=_();
ae(a,b);
}
for(int i=;i<=n;++i)ae(i,i==n?:i+);
for(int i=;i<=n;++i){
et[i][]=e0[i].data();
et[i][]=et[i][]+e0[i].size();
}
for(int i=;i<=n;++i)if(deg[i]==)q[++qr]=i;
while(ql!=qr){
int w=q[++ql];
if(deg[w]!=)break;
deg[w]=;
int cs[],cp=;
cs[cp++]=w;
for(int*l=et[w][],*r=et[w][];l!=r;++l){
int u=*l;
if(!deg[u])continue;
cs[cp++]=u;
if(==--deg[u])q[++qr]=u;
}
++idp;
for(int i=;i<;++i){
for(int j=;j<i;++j)chk(cs[i],cs[j]);
p3[idp][i]=cs[i];
}
}
for(int i=;i<=idp;++i){
lr[i][]=ee[i].data();
lr[i][]=lr[i][]+ee[i].size();
}
qp=_();
for(int i=;i<qp;++i){
int x=_(),y=_();
if(x==y)continue;
if(x>y)std::swap(x,y);
if(x==&&y==n||x+==y||h1(x,y)[]){
as[i]=;
continue;
}
as[i]=inf;
qq[x].push_back((Q){y,i});
qq[y].push_back((Q){x,i});
}
for(int i=;i<=idp;++i){
qs[i][]=qq[i].data();
qs[i][]=qs[i][]+qq[i].size();
}
f1();
for(int i=;i<qp;++i)printf("%d\n",as[i]);
return ;
}
bzoj 4449: [Neerc2015]Distance on Triangulation的更多相关文章
- 【bzoj 4449】[Neerc2015]Distance on Triangulation
Description 给定一个凸n边形,以及它的三角剖分.再给定q个询问,每个询问是一对凸多边行上的顶点(a,b),问点a最少经过多少条边(可以是多边形上的边,也可以是剖分上的边)可以到达点b. I ...
- 【BZOJ 4449】[Neerc2015]Distance on Triangulation 多边形分治结构
这题好神啊……正解方向是分治,据我所知的分治方法有:I.离线后直接对多边形以及所有的询问进行分治 II.建立多边形的分治结构(对于三角形来说类似线段树,对于对角线来说类似平衡树),然后每次在这个分治结 ...
- BZOJ4449 : [Neerc2015]Distance on Triangulation
首先拓扑,每次取出度数为$2$的点,这样可以把所有三角形都找到. 那么建出对偶图,会发现是一棵树. 对这棵树进行点分治,每次取出重心,DFS求出所有在里面的点,然后从重心$3$个点分别做一次BFS. ...
- Gym 100851 Distance on Triangulation
题意:给你一个N边形, 然后这个n边形有n-3条边,然后询问2点之间的最短路. 题解:分治. 我们可以找到一条边,使得这幅图能分成大小相同的2幅图,那么我们就可以确定那些被分割开的询问的答案是多少了. ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- NOIP模拟赛 城市
题目描述 $ZZQ$ 是一国之主. 这个国家有$N$个城市, 第$i$个城市与第$(i + 1) (mod N)$和$(i - 1) (mod N)$在一个正$N$边形相连. $ZZQ$ 又新建了$N ...
- Week Two
2018.12.3: 1.[BZOJ 4819] 2.[BZOJ 4827] 3.[P1919] 4.[FFT模板] 2018.12.4: 1.[NTT] 2.[MTT(CRT)] 3.[MTT(my ...
- NEERC15
2015-2016 ACM-ICPC Northeastern European Regional Contest 再开一个新坑吧 目前姿势有限,C.H.I仍然处于弃坑状态 代码戳这里 Problem ...
- 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计
Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...
随机推荐
- iis 7 asp.net ajax post 请求字节过大报错问题解决办法
遇到一个ajax post 提交新闻资讯类的文章,报 {"Message":"There was an error processing the request.&quo ...
- zoj2112&&bzoj1901
题解: 可修改的主席树 一开始,我就按照最暴力的方法,空间nlognlogn 然后zju上面过不了,bzoj没有权限号 然后,参考了往上的论文,发现可以把初始的主席树先建好 然后,每次只需要维护修改的 ...
- 通过Viewpager 来实现微信界面左右滑动。
package com.lixu.huadong; import java.util.ArrayList; import android.os.Bundle; import android.suppo ...
- python 数据科学
参考资料: https://www.yiibai.com/python_data_science/python_bubble_charts.html
- Spring Data操作Redis时,发现key值出现 \xac\xed\x00\x05t\x00\tb
原文链接:http://blog.csdn.net/yunhaibin/article/details/9001198 最近在研究redis,以及spring data对redis的支持发现了一个奇怪 ...
- 如何提升ACTION_SIM_STATE_CHANGED的接收速度?
在Android中,BroadcastReceiver分动态注册和静态注册. 静态注册的一个优势就是:当你的BroadcastReceiver可以接受系统中 某个broadcast时,系统会自动启动你 ...
- centos下tomcat启动卡死
遇到好几次了,总是忘记哪个位置~!!! tomcat启动时查看日志会卡在一个位置很长时间,如下 28-Aug-2018 22:56:55.216 INFO [localhost-startStop-1 ...
- Python学习(001)--计算机基础
操作系统发展历史 操作系统并不是与计算机硬件一起诞生的,它是在人们使用计算机的过程中,为了满足两大需求:提高资源利用率.增强计算机系统性能,伴随着计算机技术本身及其应用的日益发展,而逐步地形成和完善起 ...
- magento的常用调用
1,CMS调用网站的Url <a href="{{store direct_url="about-us"}}">About Us</a> ...
- TensorBoard 实践 1
从新查看图的时候,删除旧的logs/下面的文件 tf.scalar_summary('loss',self.loss) AttributeError: 'module' object has no a ...