code for 1 - 分治
2017-08-02 17:23:14
writer:pprp
题意:将n分解为n/2, n%2, n/2三部分,再将n/2分解。。得到一个序列只有0和1,给出[l, r]问l到r有几个1
题解:分治
代码及分析如下:
#include <iostream> using namespace std; typedef __int64 ll; //L,R是查询区间,l,r是计算出的分解以后的长度 ll query(ll L ,ll R,ll l,ll r, ll n) { if(l == r) return n; //分治 ll mid = (l+r)>>1; ll ans = 0; //在左侧进行递归 if(L <= mid - 1) ans += query(L,R,l,mid - 1,n>>1); //在右侧进行递归查找 if(R >= mid + 1) ans += query(L,R,mid + 1,r,n>>1); //这个时候对mid进行处理,判断条件是mid在查询范围区间内 if(mid <= R && mid >= L) ans += n%2; return ans; } //该函数是用来求分解n以后的位数
//也可以看出一个规律,某个数的展开以后的位数是刚好大于二次幂的值减去1,比如3的展开为4-1,4的展开为8-1 ll f(ll n) { if(n == 1 || n == 0) return 1; return 2 * f(n >> 1) + 1; } int main() { ll n; ll l, r; cin >> n >> l >> r; cout << query(l,r,1,f(n),n) << endl; return 0; }
代码改变世界