P5968 [POI2017]Reprezentacje ró?nicowe 暴力+二分

题意:

给定一个数列 a:

  • \(n\le 2\) 时,a_n=na**n=n
  • \(n>2\),且 n 是奇数时, \(a_n=2\times a_{n-1}\)
  • \(n>2\),且 n 是偶数时,\(a_n=a_{n-1}+r_{n-1}\)

其中 \(r_{n-1}= \operatorname{mex}(|a_i-a_j|)(1\le i\le j\le n-1)mex(S)\) 表示最小的不在 S集合里面的非负整数。

数列 a 的前若干项依次为:

1,2,4,8,16,21,42,51,102,112,224,235,470,486,972,990,19801,2,4,8,16,21,42,51,102,112,224,235,470,486,972,990,1980。

可以证明,对于任意正整数 xx,只存在唯一一对整数 (p,q)满足 \(x=a_p-a_q\),定义为 \(\operatorname{repr}(x)\)

比如 \(\operatorname{repr}(17)=(6,3)\)\(\operatorname{repr}(18)=(16,15)\)。 现有 n 个询问,每次给定一个正整数 x,请求出 \(\operatorname{repr}(x)\)

分析:

第一眼,不会做/bushi

仔细观察题面,我们可以发现,偶数位置的数增长极快,因为\(a_{57}\)就已经超过1e9了。而且对于大小超过1e9的数,奇数位和前一项偶数位的差也大于1e9,所以57位之后的数,能组成题目要求的repe函数的只有偶数项和前一位奇数项。

所以我们可以暴力打出前57位能形成的数,对于查询,如果在前面57项里查到了就输出。否则的话,需要二分在表里找到最大的小于他的数,并得到他是在表里的第几个。因为r[]是递增的,那么如果当前x代表了一个r[i],也就意味着前面的x-1个数都已经被别的数对所代表了。又因为表里有num个,这是前57项里有的。那么x-num就是从57项后的第几个数对有这样一个差x。那么每一个数对2个数,又因为这样的计算包含了最后差等于x的那个数对,所以答案就是

\[( 57+(x-num)*2-1,57+(x-num)*2-2 ) \]

代码:

#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	map <int ,pair<int ,int > > s;
	typedef map<int ,pair<int ,int > >::iterator it;
	int t,n;
	int a[100],b[10000],cnt;
	 
	void work()
	{
	    a[1]=1,a[2]=2;
	    s[1]=make_pair(2,1);
	    for(n=3;;n++)
	    {
	        if(n&1) a[n]=a[n-1]*2;
	        else
			{
				for(int j=1;;j++)
				{
					if(!s.count(j))
					{
					 a[n]=a[n-1]+j;
					 break; 
					}
				} 
			} 
	        for(int j=1;j<n;j++)
			{
				s[a[n]-a[j]]=make_pair(n,j);
			}
	        if((!(n&1))&&a[n]>1e9) break;
	    }
	    for(it l=s.begin();l!=s.end();l++)
	    {
	    	b[++cnt]=l->first;
		}
	    scanf("%d",&t);
	    while(t--)
	    {
	        int x;
	        scanf("%d",&x);
	        it l=s.find(x);
	        if(l!=s.end())
	        {
	        	printf("%d %d\n",l->second.first,l->second.second);
			}
	        else
	        {
	            int y=lower_bound(b+1,b+cnt+1,x)-b-1;
	            printf("%d %d\n",n+(x-y)*2,n+(x-y)*2-1);
	        }
	    }
	}


}

int main()
{
	zzc::work();
	return 0;
 } 
 
posted @ 2020-09-14 08:02  youth518  阅读(160)  评论(0编辑  收藏  举报