JZOJ 3769.【NOI2015模拟8.14】A+B

强颜欢笑 提交于 2019-12-21 19:59:01

DescriptionDescription

定义斐波那契表示序列是用形如y=i=1FbiAiy=\sum_{i=1}^{\infty}Fb_iA_i表示yy的序列AA

给定两个长度为n,mn,m的斐波那契最大表示序列,求它们和的斐波那契最大表示序列

定义更大的斐波那契序列是在长度更大的基础上,字典序尽量大

数据范围:n106n\leq 10^6


SolutionSolution

首先两个表示序列先相加,然后重复以下操作直到序列中只有0或1(易证这样的情况下是最优的)

对于相邻的1,不断做合并

对于各种的2,前后发散

由于在最坏条件下算法会跌落成O(n2)O(n^2),但是似乎也没有什么更好的解法了

于是就O()O(玄学)过掉了


CodeCode

#include<cctype>
#include<cstdio>
#include<algorithm> 
#define LL long long
#define N 1000100
using namespace std;int n,m,a[N],l,b[N],t;
bool flag=1;
inline LL read()
{
	char c;LL d=1,f=0;
	while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
	while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
	return d*f;
}
signed main()
{
	n=read();for(register int i=1;i<=n;i++) a[i]=read();
	m=read();for(register int i=1;i<=m;i++) b[i]=read();
	l=max(n,m)+30;
	if(a[1]) b[!b[1]]=1;a[1]=0;
	for(register int i=1;i<=l;i++) b[i]+=a[i];
	while(flag)
	{
		for(register int i=1;i<=l;i++) if(b[i]&&b[i-1]) t=min(b[i],b[i-1]),b[i+1]+=t,b[i-1]-=t,b[i]-=t;
		flag=false;
		for(register int i=++l;i>0;i--) if(b[i]>1) {b[i+1]++;b[i]-=2;if(i>1) b[i-2]++;flag=true;}
	}
	while(b[l]==0) l--;
	printf("%d ",l);b[1]+=b[0];
	for(register int i=1;i<=l;i++) printf("%d ",b[i]);
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!