版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82149564
原题地址:http://codeforces.com/problemset/problem/768/B
题意:有一个序列,刚开始,只有
个数
,接着按照以下顺序变化:
找到序列中任意一个>1的数p,将他变为
,
,
直到所有点数都不大于
为止。 问最后的序列 区间
中有多少个
思路:我们可以找规律知道,每一个数字可以分为3部分,其中第一部分和第三部分都是相同的.
那么基于这个规律,我们可以通过递归分治的方法来解决这个问题.
#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
ll n, l, r;
ll sum(ll n) {
ll x = log2(n);
return (1LL << (x + 1)) - 1;
}
ll query(ll n, ll L, ll R, ll l, ll r) {
if (l <= L && r >= R) return n;
if (n == 0) return 0;
if (R < l) return 0;
if (L > r) return 0;
ll mid = (L + R) / 2;
return query(n / 2, L, mid - 1, l, r) + query(n % 2, mid, mid, l, r) + query(n / 2, mid + 1, R, l, r);
}
int main() {
scanf("%lld%lld%lld", &n, &l, &r);
printf("%lld\n", query(n, 1, sum(n), l, r));
return 0;
}