程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu4737A Bit Fun 線段樹

hdu4737A Bit Fun 線段樹

編輯:C++入門知識

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) ;
    }
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved