#include <cstdio>
int d[40020],i=1; // d 记录压缩码(显然恒小于等于 40002 ) , i 用来记录存储的位置
char c; // 临时存储字符
int main()
{
for(;scanf("%c",&c)&&c>0x2F;) // 先读入第一行,不断读入,直到 c 不是 ‘0’(0x30) 和 ‘1’ (0x31) 为止。
i+=!(i&1^(c-0x30)),d[i]++, d[0]++; // 空格以前为祖传神秘代码,解释放到最后;空格以后表示 N 的值自加
// 至此,d[0] 为 N 的值
for(;~scanf("%c",&c);)if( c>0x2F)i+=!(i&1^(c-0x30)),d[i]++; // 不断读入,如果每次内容是 ‘0’ 或 ‘1’ 则 执行祖传语句
for(int j=0;j<=i;j++)printf("%d ",d[j]); // 输出存储好的压缩码
}
** 现在解释 i+=!(i&1^(c-0x30)),d[i]++; **
首先计算 (c-0x30) , 很显然,当 c 为 ‘0’ 时,值为 0 , 当 c 为 ‘1’ 时,值为 1 ;
然后计算 i&1 , 当 i 为奇数时,值为 1 , 否则值为 0 ;
然后计算 (i&1^(c-0x30)) : 当 i 为奇数且 c 为 ‘0’ 时,或 i 为偶数且 c 为 ‘1’时,值为1;否则值为 0 。 (表示 c 是否应该计算到 i 的位置上)
接下来计算 !(i&1^(c-0x30)) , 如果 c 应该被计算到 d[i] 上 ,值为 0 ,否则为 1 。
接下来处理 i+=!(i&1^(c-0x30)) , 如果 c 应该被计算到 d[i] 上,i 不变,否则 i ++ 。
最后就是 i+=!(i&1^(c-0x30)),d[i]++ ,先设置好 i 的位置,然后执行 d[i] ++ 。