CodeForces 232C Doe Graphs(分治+搜索)
题意
题意翻译
\(Doe\)以她自己的名字来命名下面的无向图
\(D(0)\)是只有一个编号为\(1\)的结点的图.
\(D(1)\)是只有两个编号分别为\(1\)和\(2\)的点与一条连接这两个点的边的图.
\(D(n)\)以如下方法构造
将\(D(n-2)\)中所有点的编号加上\(|D(n-1)|\)
在点\(|D(n-1)|\)与点\(|D(n-1)|+1\)之间连边。
在点\(|D(n-1)|+1\)与点1之间连边
现在\(Doe\)已经构造出了\(D(n)(n\leq 100)\),她会多次询问你在这张图中\(a\ b\)两点间的最短路

输入输出格式
输入格式:
The first line contains two integers \(t\) and \(n\) ( \(1\leq t\leq 10^{5}; 1\leq n\leq 10^{3}\) ) — the number of queries and the order of the given graph. The \(i\)-th of the next \(t\) lines contains two integers \(a_{i}\) and \(b_{i}\) ( \(1\leq a_{i},b_{i}\leq 10^{16}, a_{i}\neq b_{i}\) ) — numbers of two vertices in the \(i\)-th query. It is guaranteed that \(a_{i},b_{i}\leq |D(n)|\).
Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use cin, cout streams or the %I64d specifier.
输出格式:
For each query print a single integer on a single line — the length of the shortest path between vertices \(a_{i}\) and \(b_{i}\). Print the answers to the queries in the order, in which the queries are given in the input.
输入输出样例
输入样例#1:
10 5
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
输出样例#1:
1
1
1
2
1
2
3
1
2
1
思路
首先想到,每张图的点的数量是有规律的:
\]
这不就是斐波那契数列吗?我们不妨直接记\(F(n)\)为\(D(n)\)的顶点数。
然后考虑查询两点\(a\ b\)在\(D(n)\)中的最短路,一开始我的想法是这样的:如果有\(1\leq a,b\leq F(n-1)\),那么\(a\ b\)在\(D(n)\)中的最短路也就是在\(D(n-1)\)中的最短路;如果有\(F(n-1)< a,b\leq F(n)\),那么\(a\ b\)在\(D(n)\)中的最短路也就是在\(D(n-2)\)中的最短路。其余的情况再分治下去。但是这是有问题的,因为有的时候两点可以绕到下一张图上去,然后再绕回一张图中,这样的距离可能会更短。
具体来说,一共有这几种情况:
- \(a\ b\)都在\(D(n-1)\)的范围内:
- \(a\)直接走图\(D(n-1)\)到达\(b\);
- \(a\)通过点\(1\)走到图\(D(n-2)\),再绕回到图\(D(n-1)\),到达\(b\);
- \(a\)通过点\(F(n-1)\)走到图\(D(n-2)\),再绕回到图\(D(n-1)\),到达\(b\)。
- \(a\ b\)都在\(D(n-2)\)的范围内:
- \(a\)直接走图\(D(n-2)\)到达\(b\)。
- \(a\)在\(D(n-1)\)范围内,而\(b\)在\(D(n-2)\)范围内:
- \(a\)通过点\(1\)走到图\(D(n-2)\),再走到\(b\);
- \(a\)通过点\(F(n-1)\)走到图\(D(n-2)\),再走到\(b\)。
那么我们就可以在搜索的过程中分类讨论来优化了。
但是这样还是会\(TLE\)。接下来,我们发现有多次重复询问是关于\(a\)点如何最快到达\(1\)点或者\(F(n-1)\)点,我们就可以先把它预处理出来,再搜索。具体实现见代码。
AC代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL n,m,f[1005],d[1005],d1[1005],d2[1005],d3[1005],d4[1005];
LL read()
{
LL re=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) re=(re<<3)+(re<<1)+ch-'0',ch=getchar();
return re;
}
void prework(LL x,LL g,LL *a1,LL *a2)
{
if(!g){a1[g]=a2[g]=0;return ;}
if(g==1){a1[g]=(x==2),a2[g]=(x==1);return ;}
if(x<=f[g-1])
{
prework(x,g-1,a1,a2);
a1[g]=min(a1[g-1],a2[g-1]+2);
a2[g]=min(a1[g-1],a2[g-1])+1+d[g-2];
}
else
{
prework(x-f[g-1],g-2,a1,a2);
a1[g]=a1[g-2]+1;
a2[g]=a2[g-2];
}
}
LL ask(LL g,LL x,LL y)
{
if(g<=1) return x!=y;
if(x<=f[g-1]&&y<=f[g-1]) return min(ask(g-1,x,y),min(d1[g-1]+d4[g-1],d2[g-1]+d3[g-1])+2);
if(x<=f[g-1]&&y>f[g-1]) return min(d1[g-1],d2[g-1])+1+d3[g-2];
else return ask(g-2,x-f[g-1],y-f[g-1]);
}
int main()
{
f[0]=1,f[1]=2,d[0]=0,d[1]=1;
for(LL i=2;i<80;i++) f[i]=f[i-1]+f[i-2],d[i]=d[i-2]+1;
m=read(),n=min(read(),LL(80));
while(m--)
{
LL x=read(),y=read();if(x>y) swap(x,y);
prework(x,n,d1,d2);prework(y,n,d3,d4);
printf("%lld\n",ask(n,x,y));
}
return 0;
}
CodeForces 232C Doe Graphs(分治+搜索)的更多相关文章
- CodeForces - 586D Phillip and Trains 搜索。vis 剪枝。
http://codeforces.com/problemset/problem/586/D 题意:有一个3*n(n<100)的隧道.一个人在最左边,要走到最右边,每次他先向右移动一格,再上下移 ...
- Codeforces Gym 100431B Binary Search 搜索+组合数学+高精度
原题链接:http://codeforces.com/gym/100431/attachments/download/2421/20092010-winter-petrozavodsk-camp-an ...
- Codeforces - 559B - Equivalent Strings - 分治
http://codeforces.com/problemset/problem/559/B 这个题目,分治就好了,每次偶数层可以多一种判断方式,判断它的时间就是logn的(吧),注意奇数层并不是直接 ...
- Codeforces 848C (cdq分治)
Codeforces 848C Goodbye Souvenir Problem : 给一个长度为n的序列,有q个询问.一种询问是修改某个位置的数,另一种询问是询问一段区间,对于每一种值出现的最右端点 ...
- Luogu P2101 命运石之门的选择(分治+搜索)
P2101 命运石之门的选择 题意 题目描述 在某一条不知名世界线的冈伦今天突然接到了一条\(dmail\),上面说世界线将会发生巨大变动,未来的他无论如何都无法扭转这种变动回到原来的世界线.而世界线 ...
- Codeforces 938G 线段树分治 线性基 可撤销并查集
Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...
- Codeforces 1553I - Stairs(分治 NTT+容斥)
Codeforces 题面传送门 & 洛谷题面传送门 u1s1 感觉这道题放到 D1+D2 里作为 5250 分的 I 有点偏简单了吧 首先一件非常显然的事情是,如果我们已知了排列对应的阶梯序 ...
- Codeforces 1010F - Tree(分治 NTT+树剖)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题. 首先我们考虑按照这题的套路,记 \(t_i\) 表示 \(i\) 上的果子数量减去其儿子果子数量之和,那么对于一个合法的放置果子 ...
- Codeforces 586D. Phillip and Trains 搜索
D. Phillip and Trains time limit per test: 1 second memory limit per test :256 megabytes input: stan ...
随机推荐
- 【JZOJ6350】考试(test)
description analysis 对于\(n=0\)的点,直接模拟就好了 状压\(DP\),设\(f[i][j][S]\)表示到第\(i\)题.连续\(GG\)了\(j\)题.喝的饮料集合为\ ...
- C++ 字符串相互转换 适合 lua project
#include <iostream> #include <Windows.h> #include <assert.h> #define Main main voi ...
- R语言 数据重塑
R语言数据重塑 R语言中的数据重塑是关于改变数据被组织成行和列的方式. 大多数时间R语言中的数据处理是通过将输入数据作为数据帧来完成的. 很容易从数据帧的行和列中提取数据,但是在某些情况下,我们需要的 ...
- thinkphp 分布式数据库支持
ThinkPHP内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型. 配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持.如果采用分布式数据库, ...
- js 常见功能总会
一.随着页面滚动,元素到达可视区域,显示特殊样式 <!DOCTYPE html> <html lang="en"> <head> <met ...
- (15)python打包
.py文件在没有安装python软件的电脑上是不能被执行的
- maven项目依赖其他jar包的时候,idea运行没问题,java -jar 报错:java.lang.SecurityException: Invalid signature file digest
当项目依赖其他jar包的时候,打出的jar包执行出错,抛出这个异常. 原因:因为依赖jar包中的META-INF中有多余的.SF文件与当前jar包冲突, 解决方案 一 在打包前删除依赖jar包的.SF ...
- JS while 循环
while循环:只要条件成立,就重复不断的执行循环体代码 while(条件判断) { 如果条件为true,则执行循环体代码 } while循环结构说明: 在循环开始前,必须要对变量初始化(声明变量 ...
- 初识OpenCV-Python - 002: Drawing functions
使用OpenCV-Python 的画图函数画图. 本次的图形函数有: cv2.line(), cv2.circle(), cv2.rectangle(), cv2.ellipse(), cv2.put ...
- 【LGP4714】「数学」约数个数和
题目 众所周知,除数个数函数\(\sigma_0=I^2\),\(I\)就是狄利克雷卷积里的\(1\)函数 于是熟悉狄利克雷卷积的话很快就能看出我们要求的就是\(I\times I^{k}\),即\( ...