设为首页 加入收藏

TOP

hdu4737A Bit Fun 线段树
2015-11-21 00:56:52 来源: 作者: 【 】 浏览:1
Tags:hdu4737A Bit Fun 线段
//给一串序列,问有多少对[i,j]使得
//[i,j]区间的所有数的或的值小于m
//可以知道'或'操作的加(a|b)>=max(a,b)
//可以枚举区间的右边r,找左边第一个不满足的位置
//然后在它们中间的r为由边界的区间都没满足
//对于找第一个不满足的位置,可以用线段树做,
#include
   
     #include
    
      #include
     
       using namespace std ; const int maxn = 100010 ; #define left v << 1 #define right v<<1|1 struct node { int l , r ; int value ; }tree[maxn<<2] ; int h[maxn] ; int m ,n; void build(int l , int r , int v) { tree[v].l = l ; tree[v].r = r ; if(l == r) { tree[v].value = h[l] ; return ; } int mid = (l + r) >> 1 ; build(l , mid , left) ; build(mid + 1 , r , right) ; tree[v].value = tree[left].value|tree[right].value ; } int get_ans(int v , int sum) { if(tree[v].l == tree[v].r) return tree[v].l ; int mid = (tree[v].l + tree[v].r) >> 1 ; if((sum|tree[right].value) >= m) return get_ans(right , sum) ; else return get_ans(left , sum|tree[right].value) ; } int ans = 0 ; int query(int v , int pos) { if(tree[v].l == tree[v].r) return tree[v].value ; int mid = (tree[v].l + tree[v].r) >> 1 ; int sum ; if(pos <= mid) query(left , pos) ; else { sum = query(right , pos) ; if(sum < m && (sum|tree[left].value) >= m) {ans = get_ans(left , sum) ;} return sum|tree[left].value; } } int main() { //freopen(in.txt ,r ,stdin) ; int T ; scanf(%d ,&T) ; int cas = 0 ; while(T--) { scanf(%d%d ,&n , &m) ; for(int i = 1;i <= n;i++) scanf(%d ,&h[i]) ; build(1 , n , 1) ; int sum = 0; for(int i = 1;i <= n ;i++) { ans = 0 ; if(h[i] >= m) {continue;} query(1 , i) ; sum += (i - ans); } query(1 , 9) ; printf(Case #%d: ,++cas) ; printf(%d ,sum) ; } } 
     
    
   

?

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 2665 Kth number 主席树裸题 下一篇letcode - Dungeon Game

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: