其他分享
首页 > 其他分享> > HDU7059 Counting Stars(势能线段树)

HDU7059 Counting Stars(势能线段树)

作者:互联网

目录

Description

有三种操作

$1\ l\ r: $ 区间查询和值

$2\ l\ r: $ 将区间上的每个数都减去其 \(lowbit\)

$3\ l\ r: $ 将区间上的每个数都加上其 \(upbit\)

State

\(1<=n<=10^{5}\)

\(T<=5\)

\(1<=a[i]<=10^9\)

\(1<=q<=10^5\)

Input

1

5

5 2 2 9 7

4

2 1 5

1 1 1

3 1 3

1 2 5

Output

4

14

Solution

这个题的基本思路还是很好想的,\(2\) 操作单点更新就可以;

\(3\) 操作如果仍然单点更新,只有等到这个区间上所有的数都为 \(2^k\) 时才可以区间更新,而且在此之前的单点更新都要寻找对应的 \(upbit\) ,不妨操作有些繁琐,如果 \(3\) 操作本身的值就是 \(2^k\) 就可以进行区间更新简化时间了

所以将 \(a[i]\) 分成 \(upbit\) 和 \(a[i]-upbit\) 分别操作就可以了


Code

const int N = 1e5 + 5;

    int n, m, _, k;
    int a[N];
    ll ksm(ll a, ll x);
    struct Node
    {
        int l, r;
        ll maxx, minn;
        int lazy;
        #define lson id << 1
        #define rson id << 1 | 1
        void update(int x)
        {
            lazy += x;
            maxx = maxx * ksm(2, x) % mod;
        }
    }t[N << 2];
    vector<int> v;

ll ksm(ll a, ll x)
{
    ll ans = 1;
    while(x){
        if(x & 1) ans = ans * a % mod;
        a = a * a % mod;
        x >>= 1;
    }
    return ans;
}

void push_up(int id)
{
    t[id].maxx = (t[lson].maxx + t[rson].maxx) % mod;
    t[id].minn = (t[lson].minn + t[rson].minn) % mod;
}

void push_down(int id)
{
    int x = t[id].lazy;
    if(x){
        t[lson].update(x);
        t[rson].update(x);
        t[id].lazy = 0;
    }
}

void build(int l, int r, int id)
{
    t[id].l = l, t[id].r = r;
    t[id].lazy = 0;
    if(l == r){
        int pos = upper_bound(v.begin(), v.end(), a[l]) - v.begin() - 1;
        t[id].maxx = v[pos];
        t[id].minn = a[l] - v[pos];
    }
    else{
        int mid = l + r >> 1;
        build(l, mid, lson);
        build(mid + 1, r, rson);
        push_up(id);
    }
}

ll query(int l, int r, int id)
{
    int L = t[id].l, R = t[id].r;
    if(L >= l && r >= R){
        return (t[id].minn + t[id].maxx) % mod;
    }
    else{
        int mid = L + R >> 1;
        push_down(id);
        ll ans = 0;
        if(mid >= l) ans = (ans + query(l, r, lson)) % mod;
        if(r >= mid + 1) ans = (ans + query(l, r, rson)) % mod;
        push_up(id);
        return ans;
    }
}

void update(int l, int r, int id) //+
{
    int L = t[id].l, R = t[id].r;
    if(L >= l && r >= R){
        t[id].update(1);
    }
    else{
        int mid = L + R >> 1;
        push_down(id);
        if(mid >= l) update(l, r, lson);
        if(r >= mid + 1) update(l, r, rson);
        push_up(id);
    }
}

void modify(int l, int r, int id) //-
{
    int L = t[id].l, R = t[id].r;
    if(L >= l && r >= R && t[id].maxx == 0){
        return ;
    }
    if(L == R){
        if(t[id].minn == 0){
            t[id].maxx = 0;
            return ;
        }
        t[id].minn = t[id].minn - lowbit(t[id].minn);
        return ;
    }
    {
        int mid = L + R >> 1;
        push_down(id);
        if(mid >= l) modify(l, r, lson);
        if(r >= mid + 1) modify(l, r, rson);
        push_up(id);
    }
}

signed main()
{
    //IOS;
    for(int i = 0; i < 31; i ++){
        v.pb(1 << i);
    }
    rush(){
        sd(n);
        rep(i, 1, n) sd(a[i]);
        build(1, n, 1);
        sd(m);
        int l, r, opt;
        while(m --> 0){
            sddd(opt, l, r);
            if(opt == 1){
                ll ans = query(l, r, 1);
                pll(ans);
            }
            else if(opt == 2){
                modify(l, r, 1);
            }
            else{
                update(l, r, 1);
            }
        }
    }
    //PAUSE;
    return 0;
}

标签:minn,int,ll,HDU7059,mid,Stars,ans,Counting,id
来源: https://www.cnblogs.com/Segment-Tree/p/15328403.html