题目链接:http://codeforces.com/contest/768/problem/B
题意:
有一个序列,刚开始,只有1个数n,接着按照以下顺序变化:
1:找到序列中任意一个>1的数p,将他变为 p/2, p%2, p/2
直到所有点数都不大于1为止。
问最后的序列 l-r 中有多少个1
题解:
md这道题直接用分治搞就可以了。。我写一个T一个
代码:
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long LL;
inline void quick_IO() { ios::sync_with_stdio(false); cout.tie(0); cin.tie(0); }
// 分治算法
LL nm(LL p) {
if(p<=1) return p;
return nm(p/2)*2+1;
}
int dfs(LL num, LL L, LL R, LL l, LL r) {
if(R < l || L > r || num == 0) return 0;
if(num == 1) return 1;
LL mid = l+nm(num/2);
return dfs(num/2, L, R, l, mid-1)+dfs(num%2, L, R, mid, mid)+dfs(num/2, L, R, mid+1, r);
}
int main() {
quick_IO();
LL n, l, r;
cin >> n >> l >> r;
LL ans = nm(n);
int res = dfs(n, l, r, 1, ans);
cout << res << endl;
return 0;
}