hdu3830 (二分+LCA)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

Checkers

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others)
Total Submission(s): 775    Accepted Submission(s): 228

Problem Description

Little X, Little Y and Little Z are playing checkers when Little Y is annoyed. So he wants to make the chessboard much bigger. Although Little Z insists the original version, Little X stands by Little Y. After they enlarge the chessboard, the chessboard turns to an infinite line. 
The chessboard is like the Number Axes now, with each integer point able to hold a checker. At initial status there are three checkers on three different integer points , and through the game there always are three checkers. Every time, they can choose a checker A to jump across a pivot checker B to a new position(but the distance between old A and B equals to new A and B, and there should be no other checkers except B in the range [old A, new A]).
After playing for a while, they wonder whether an given status a,b,c can be transferred to x,y,z. obeying the rules. Since the checkers are considered the same, it is unnecessary for a must jump to x.

Input

The first line is a,b,c.
The second line is x,y,z.
They are all integers in range (-10^9, 10^9) and the two status are valid.

Output

The first line is YES or NO, showing whether the transfer can be achieved.
If it is YES, then output the least steps in the second line.

Sample Input

1 2 3
0 3 5

Sample Output

YES
2

Hint

The middle checker jumps to position 0, and the status is 0 1 3
Then , the middle one jumps to 5.

Source

2011 Multi-University Training Contest 1 - Host by HNU

 

题意:

给出三个点数轴上的起始为止与终止位置,问能否通过不断的跳跃从起始位置到终止位置(ps:不需要一一对应),每次跳跃时不得跨过两个点,若能,则给出最少需要几次操作

分析:

不妨设a<b<c,x<y<z。

由于一次不能跨越两个点。若b-a>c-b,则只能进行(1)b->2a-b-a或者(2)b->2c-b或者(3)a->2b-a;

若b-a<c-b,则只能进行(1)b->2a-b-a或者(2)b->2c-b或者(3)c->2b-c;

若b-a=c-b,则只能进行(1)b->2a-b-a或者(2)b->2c-b;

我们可以发现,若每次选取(1)(2)操作,则三个数在数轴上的跨度会不断变大,我们可以视为其分别向左儿子和右儿子移动,

若选取(3)操作,则三个数在数轴上的跨度会不断变小,对此,我们可以将其视为向父亲结点移动(因为对于每种状态,其对应的(3)操作是唯一的,这恰好对应这树的父亲结点是唯一的)。

通过一定次数的向父亲结点移动,我们可以发现最终一定会变成第三种状态。也就是对于判断yes还是no,我们只需要判断其所对应的根节点是否相同,若不同,则必定不能从初始状态转移到最终状态。

那么,如何快速地求出某一状态进行若干操作之后的状态呢?

我们假设a<b<c,并且c-b>a-b。那么,一次(3)操作之后会变成b,2b-a,c。也就是相当于给a和b同时加上了b-a。那么对于这样需要移动几次呢?(c-b)/(b-a)?

这是不对的,例如1,2,4。若移动二次,则会变成3,4,4。也就是我们要避免b-a=c-b的发生。即对于(c-b)%(b-a)==0时,我们需要少移一次。

于是,利用向下取整的特性,我们可以发现只要移(c-b-1)/(b-a)次。

如此,不断往复,我们就可以快速地求出移动若干次的状态,然后二分搞一下就行了

  1 //#####################
  2 //Author:fraud
  3 //Blog: http://www.cnblogs.com/fraud/
  4 //#####################
  5 #include <iostream>
  6 #include <sstream>
  7 #include <ios>
  8 #include <iomanip>
  9 #include <functional>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <string>
 13 #include <list>
 14 #include <queue>
 15 #include <deque>
 16 #include <stack>
 17 #include <set>
 18 #include <map>
 19 #include <cstdio>
 20 #include <cstdlib>
 21 #include <cmath>
 22 #include <cstring>
 23 #include <climits>
 24 #include <cctype>
 25 using namespace std;
 26 #define XINF INT_MAX
 27 #define INF 0x3FFFFFFF
 28 #define MP(X,Y) make_pair(X,Y)
 29 #define PB(X) push_back(X)
 30 #define REP(X,N) for(int X=0;X<N;X++)
 31 #define REP2(X,L,R) for(int X=L;X<=R;X++)
 32 #define DEP(X,R,L) for(int X=R;X>=L;X--)
 33 #define CLR(A,X) memset(A,X,sizeof(A))
 34 #define IT iterator
 35 typedef long long ll;
 36 typedef pair<int,int> PII;
 37 typedef vector<PII> VII;
 38 typedef vector<int> VI;
 39 #define MAXN 10
 40 ll a[MAXN],b[MAXN];
 41 ll ra[MAXN],rb[MAXN];
 42 void gcd(ll *x,ll &d){
 43     ll l1=x[1]-x[0];
 44     ll l2=x[2]-x[1];
 45     ll t;
 46     while(l1!=l2){
 47         if(l1<l2){
 48             t=(l2-1)/l1;
 49             ll tmp=t*l1;
 50             x[0]+=tmp;
 51             x[1]+=tmp;
 52         }else{
 53             t=(l1-1)/l2;
 54             ll tmp=t*l2;
 55             x[1]-=tmp;
 56             x[2]-=tmp;
 57         }
 58         d+=t;
 59         l1=x[1]-x[0];
 60         l2=x[2]-x[1];
 61         //gcd(x,d);
 62     }
 63 }
 64 void gao(ll *x,ll d){
 65     ll l1=x[1]-x[0];
 66     ll l2=x[2]-x[1];
 67     ll t;
 68     while(d>0){
 69         if(l1<l2){
 70             t=(l2-1)/l1;
 71             if(t>d)t=d;
 72             ll tmp=t*l1;
 73             x[0]+=tmp;
 74             x[1]+=tmp;
 75         }else {
 76             t=(l1-1)/l2;
 77             if(t>d)t=d;
 78             ll tmp=t*l2;
 79             x[1]-=tmp;
 80             x[2]-=tmp;
 81         }
 82         d-=t;
 83         l1=x[1]-x[0];
 84         l2=x[2]-x[1];
 85     }
 86 }
 87
 88 int main()
 89 {
 90     ios::sync_with_stdio(false);
 91     while(scanf("%I64d%I64d%I64d",&a[0],&a[1],&a[2])!=EOF){
 92         for(int i=0;i<3;i++)scanf("%I64d",&b[i]);
 93         sort(a,a+3);
 94         sort(b,b+3);
 95         for(int i=0;i<3;i++)ra[i]=a[i];
 96         for(int i=0;i<3;i++)rb[i]=b[i];
 97         ll d1=0,d2=0;
 98         bool flag=0;
 99         for(int i=0;i<2;i++)if(ra[i]==ra[i+1])flag=1;
100         for(int i=0;i<2;i++)if(rb[i]==rb[i+1])flag=1;
101         if(flag){
102             printf("NO\n");
103             continue;
104         }
105         gcd(ra,d1);
106         gcd(rb,d2);
107         flag=0;
108         for(int i=0;i<3;i++)
109             if(ra[i]!=rb[i])flag=1;
110         if(flag){
111             printf("NO\n");
112             continue;
113         }
114         printf("YES\n");
115         ll ans = 0;
116         ll tmp = 0;
117         if(d1>d2)gao(a,d1-d2);
118         else gao(b,d2-d1);
119         ll l=0,r=min(d1,d2);
120         while(l<=r){
121             ll mid=(l+r)>>1;
122             for(int i=0;i<3;i++)ra[i]=a[i];
123             for(int i=0;i<3;i++)rb[i]=b[i];
124             gao(ra,mid);
125             gao(rb,mid);
126             bool flag=0;
127             for(int i=0;i<3;i++)
128                 if(ra[i]!=rb[i])flag=1;
129             if(!flag){
130                 tmp=mid;
131                 r=mid-1;
132             }else {
133                 l=mid+1;
134             }
135         }
136         printf("%I64d\n",tmp*2+max(d1-d2,d2-d1));
137     }
138     return 0;
139 }
时间: 2024-12-23 13:29:30

hdu3830 (二分+LCA)的相关文章

NOIP2015 运输计划(二分+LCA+差分)

4326: NOIP2015 运输计划 Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 308  Solved: 208[Submit][Status][Discuss] Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 ui

P2680 运输计划[二分+LCA+树上差分]

题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n?1 条双向航道,每条航道建立在两个星球之间,这 n-1n?1 条航道连通了 LL 国的所有星球. 小 P 掌管一家物流公司, 该公司有很多个运输计划,每个运输计划形如:有一艘物流飞船需要从 u_i*u**i* 号星球沿最快的宇航路径飞行到 v_i*v**i* 号星球去.显然,飞船驶过一条航道是需要时间的,对于航道 jj,任意飞船驶过它所花费的时间为 t_j*t**j*,并且任意两艘飞船之间不会产生任

二分算法~~~大综合

二分:一个非常神奇的算法:永远记住二分,分的是答案,直接在答案在的区间范围中二分,分出一个值,就判断是不是           答案,并进行转移 二分答案: 如果已知候选答案的范围[min,max],有时候我们不必通过计算得到答案,只需在此范围内应用“二分”的过程,逐渐靠近答案(最后,得到答案)! 一.何时可以使用“二分答案” 不是任何题目都适合使用“二分答案”的,我Sam观察到一般有以下的一些特征: A. 候选答案必须是离散的 ,且已知答案的范围是:[最小值min, 最大值max] (连续区间

hdu 6031 Innumerable Ancestors(LCA+剪枝)

题目链接:hdu 6031 Innumerable Ancestors 题意: 给你一棵n个节点的树,现在有m个询问,每次给你两个点集a,b. 让你从a,b点集中选两个点x,y,使得这两个点的LCA的深度最大. 题解: 标解应该是二分+LCA,不过我试了一下暴力,稍微剪了点枝,就直接过去了. 具体看代码 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;i++) 3 using namespace std; 4 c

学习 LCA&amp;&amp;RMQ

参考:点击打开链接 点击打开链接      点击打开链接(一些总结) 点击打开链接(不错的模板) 题目:点击打开链接 花了4天时间做完了这个专题,LCA的问题用处还是很大,同时能体会RMQ的ST算法中dp的味道.基本方法就是ST,LCA转RMQ,LCA的Tarjan,LCA倍增(这个可存储边权) 这个专题后面四道题都非常好,推荐大家做做. 细节: 1. ST方法2^i 包含自己,因此其真实只包含到i+2^k-1的范围. 2. Tarjan一般都很快,但不适合修改类型的问题,关于权值长度之类的,S

LCA&amp;&amp;RMQ问题

参考:点击打开链接 点击打开链接      点击打开链接(一些总结) 点击打开链接(不错的模板) 题目:点击打开链接 花了4天时间做完了这个专题,LCA的问题用处还是很大,同时能体会RMQ的ST算法中dp的味道.基本方法就是ST,LCA转RMQ,LCA的Tarjan,LCA倍增(这个可存储边权) 这个专题后面四道题都非常好,推荐大家做做. 细节: 1. ST方法2^i 包含自己,因此其真实只包含到i+2^k-1的范围. 2. Tarjan一般都很快,但不适合修改类型的问题,关于权值长度之类的,S

题单二:图论500

http://wenku.baidu.com/link?url=gETLFsWcgddEDRZ334EJOS7qCTab94qw5cor8Es0LINVaGMSgc9nIV-utRIDh--2UwRLvsvJ5tXFjbdpzbjygEdpGehim1i5BfzYgYWxJmu ==========  以下是最小生成树+并查集=========================[HDU]1213         How Many Tables        基础并查集★1272         小

图论五百题!

生死看淡不服就淦,这才是人生! =============================以下是最小生成树+并查集======================================[HDU]1213 How Many Tables 基础并查集★1272 小希的迷宫 基础并查集★1325&&poj1308 Is It A Tree? 基础并查集★1856 More is better 基础并查集★1102 Constructing Roads 基础最小生成树★1232 畅通工程 基

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i