1214. 信号分析
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
半人马座(Centaurus)不仅有着美丽的传说,其中的比邻星还是距离太阳系最近的恒星。C博士是一直热衷于对地外文明的探测,最近他发现了一组来自半人马座的奇怪电波信号:1 1 3 1 5 3 7 1……,她怀疑这是来自那里的遥远文明对地球的问候。经过她和助手们的努力,终于发现这是一个很有规律的频率信号a1,a2,a3,……。其中a1=1,a3=3这是信号的开始标志,其余时刻的频率有如下关系:
a2n = an
a4n+1 = 2*a2n+1 - an
a4n+3 = 3*a2n+1 - 2*an
(n>=1)
信号可能很长,其中会有一些分隔标志。C博士在研究中发现这些分隔标志其实是很容易就可以判别出来的,因为它就满足an = n。
为了更进一步发掘这一长串信号的含义,C博士需要知道a1,a2,……,aL中分隔标志有多少个。
Input
只有一个整数L(1<=L<232),表示所要分析信号的长度。
Output
输出一个整数,为这段长L的信号中分隔标志的个数。
Sample Input
8
Sample Output
4
Problem Source
ZSUACM Team Member
// Problem#: 1214
// Submission#: 3586227
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
unsigned long L, sum, e[40], L1;
int b[40], s, i, k;
unsigned long f(unsigned long x) {
if (x == 1) return 1;
if (x == 3) return 3;
if (x % 2 == 0) return f(x / 2);
if (x % 4 == 1) return 2 * f((x + 1) / 2) - f((x - 1) / 4);
return 3 * f((x - 1) / 2) - 2 * f((x - 3) / 4);
}
int main() {
scanf("%lu", &L);
sum = 0;
e[0] = 1;
for (i = 1; i <= 31; i++) e[i] = 2 * e[i - 1];
s = 0;
L1 = L;
while (L1 > 0) {
s = s + 1;
b[s] = L1 % 2;
L1 /= 2;
}
for (i = 1; i < s; i++) sum += e[(i + 1) / 2 - 1];
if (s == 1) sum += 1;
else if (s % 2 == 0) {
k = s / 2;
for (i = e[k - 1]; i <= e[k] - 1; i++) {
L1 = i * e[k] + f(i);
if (L1 <= L) sum++;
else break;
}
} else {
k = (s - 1) / 2;
for (i = e[k - 1]; i <= e[k] - 1; i++) {
L1 = i * e[k + 1] + f(i);
if (L1 <= L) sum++;
else break;
L1 = i * e[k + 1] + e[k] + f(i);
if (L1 <= L) sum++;
else break;
}
}
printf("%lu\n", sum);
return 0;
}