题意:
给两个数AB表示为
∑i=1nai×f[i]
和
∑i=1mbi×f[i]
,其中a,b是一个01数组,且没有两个相邻的1,最高位一定是1。
现在问你A+B怎么也用这种表示方法表示出来。
良心补充一下输出格式,输完n以后不用换行,不然你会光荣PE.
做法:
貌似乱搞?…
假设答案是c[],先把a[]和b[]相加存入c,然后假如有一位
c[i]≥2
,这一位减去2,并且c[i+1]++,c[i-2]++。
假如有两个连续的1,c[i-1]=c[i]=1,那么c[i-1]=c[i]=0,c[i+1]++.
具体实现稍微麻烦一点点,需要考虑特殊情况。
代码:
/*************************************************************
Problem: bzoj 1534 [POI2005]Sum- Fibonacci sums
User: fengyuan
Language: C++
Result: Accepted
Time: 456 ms
Memory: 24728 kb
Submit_Time: 2017-12-31 16:58:33
*************************************************************/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cctype>
using namespace std;
typedef long long LL;
inline LL read()
{
char ch = getchar(); LL x = 0; int op = 1;
for (; !isdigit(ch); ch = getchar()) if (ch == '-') op = -1;
for (; isdigit(ch); ch = getchar()) x = x*10+ch-'0';
return op*x;
}
inline void writeAbs(LL a)
{
if (a >= 10) writeAbs(a/10);
putchar('0'+a%10);
}
inline void write(LL a)
{
if (a < 0) putchar('-');
writeAbs(abs(a));
}
const int N = 2000010;
int n, m;
int a[N], b[N], c[N];
inline void upd(int x)
{
while(c[x] == 1) {
c[x-1] = c[x] = 0; c[x+1] ++;
x += 2;
}
}
inline void change(int x)
{
if(c[x] < 2) return;
int t = x-2; if(!t) t = 1;
c[x+1] ++; if(x != 1) c[t] ++;
c[x] -= 2;
}
int main()
{
n = read(); for(int i = 1; i <= n; i ++) a[i] = read();
m = read(); for(int i = 1; i <= m; i ++) b[i] = read();
int k = max(n, m);
for(int i = k; i >= 1; i --) {
c[i] += a[i]+b[i];
if(c[i] == 2 || c[i] == 3) {
change(i); change(i+1);
if(i == 1) change(i);
}
if(c[i]) upd(i+1);
if(c[i+1]) upd(i+2);
if(c[i+2]) upd(i+3);
}
k = 2000000;
while(c[k] == 0) k --;
write(k); putchar(' ');
for(int i = 1; i <= k; i ++) { write(c[i]); if(i != k) putchar(' '); }
return 0;
}