CodeForces - 813B The Golden Age

/*

  这题今天一直RE(Runtime Error),一开始一直不明白,又怀疑到了cin对stdio的兼容,但是仍然RE
  后来发现,我忽视了乘法的溢出,也就是说,仅仅只是把数据定义为long long,以满足它们的10^18量级,仍然是不够的
  
  因为凡是乘法运算,都要警惕因为溢出变为负数的可能,这种情况下,应该把乘法用除法代替
   例如:
   while ( r >= (x * a[lena-1]) ) 和 while ( r >= (y * b[lenb-1]) )
   改为 while ( r / x >= a[lena-1]) 和 while ( r / y >= b[lenb-1] )
	   
   另外,其实这题的思路有点类似于制表,a数组是一个以1为首项,x为公比的等比数列,直到数组元素大于r时为止,b以1为首项,y为公比的等比数列。
   
   //------------此处可跳过------------
   此外,之所以a和b的大小,定义100也不会越界,是因为题目有说 x,y >= 2, 2^99的数量级达到了10^29,超过了r的数量级10^18,所以RE并不是因为数组开小了
   
   另外,附上RE常见的几种原因:
   乘法溢出 / 除以0 / 数组越界 / 指针越界 / 使用已经释放的空间 / 数组开得太大,超过了栈的范围,造成栈溢出(栈溢出一般是函数中的数组了,函数中的数组才开在栈中);不过,其实全局的数组,也是可能溢出的,维度太小,就溢出了
   //------------此处继续看------------
   
   制完表以后,就是相加,范围内的unlucky year年份压栈,一开始我觉得,如果有重复的,不就压栈了两次吗?但其实是不会影响的,因为压栈到最后,是为了找到,不出现 unlucky year的连续几年的,最大区间的,长度...如果栈中有重复元素,无非找最大值的时候,相关数据和之前的一组一样,不会影响最大值的更新
   
   另外两点就是,找golden year的最长长度之前,应该先将栈排序,因为求得的那些 unlucky year, 其实是几个单调递增区间拼到一起组成一个域,局部单调性保证不了总体的单调性,就像之前数学中,tanx的定义域和定义区间,可以类比一下...总之就是找前一定要先排序
   
   如果vector空,则其中一共r-l+1个年份,没有一个lucky year,则年份数就是golden year最大值
   
   以及,端点要单独处理,和v中的数据的处理不一样...
   因为如果是左端点和vector中的第一个元素,则左端点不作为unlucky year,右端点和vector中最后一个元素,也是同理,这两种情况下,都只有一个端点作为 unlucky year,所以算区间时减去的是1(为lucky year的那一个端点)
   
   但如果是vector中(经过排序后得到的)的两个连续元素,那么两个端点都是作为unlucky year,所以算区间时减去的是2(lucky year两个端点)
   
   
   知道了区别以后,才能更好地明白,为什么要分类讨论了
   
   最后,参考自代码:
   http://blog.csdn.net/xjh_shin/article/details/72885341
*/



#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100;
vector <LL> v;
LL a[N], b[N];

int main()
{
//	cin.tie(0);
//	cin.sync_with_stdio(false);
	LL x, y, l, r, lena, lenb;
	cin >> x >> y >> l >> r;
	a[0] = b[0] = 1;
	lena = lenb = 1;
	
	while ( r / x >= a[lena-1])
	{
		a[lena] = a[lena-1] * x;
		lena++;
	}
	while ( r / y >= b[lenb-1] )
	{
		b[lenb] = b[lenb-1] * y;
		lenb++;
	}
	v.clear();
	
	for (int i = 0; i < lena; i++)
	for (int j = 0; j < lenb; j++)
	{
		if (a[i] + b[j] >= l)
		{
			if (a[i] + b[j] > r)
			{
				 break;
			}
			v.push_back( a[i] + b[j] );
		}
	}
	sort (v.begin(), v.end());
	LL ans = 0;
	if (!v.size()) ans = r - l + 1;
	else
	{
		ans = max(v[0] - l, r - v[v.size() - 1]); //单独处理两个端点 
		//[a,b]中有(b-a+1)个元素,但是端点中有一个是unlucky year, 不算在golden age的范围里,所以在此基础上要再-1
		for (int i = 1; i < v.size(); i++)
		{
			ans = max(ans, v[i] - v[i - 1] - 1); //处理找到的unlucky year 的vector元素
			//[a,b]中有(b-a+1)个元素,但是端点都是unlucky year, 不算在golden age的范围里,所以在此基础上要再-2
		}
	}
	cout << ans << endl;
	
	
	return 0;
}


posted @ 2017-08-25 09:09  mofushaohua  阅读(227)  评论(0编辑  收藏  举报