HDU7059 +HDU7116 (线段树暴力修改)

本文探讨了如何使用线段树解决区间修改问题,重点分析了两种操作:一是区间每个数减去自己的lowbit,二是区间每个数加上highbit。通过记录区间信息,如最高位之和、其余位之和、区间是否全零以及懒标记,实现了高效的区间修改和查询。该方法适用于HDU7059和HDU7116题目。
摘要由CSDN通过智能技术生成

HDU7059 传送门

给了两种修改:
在这里插入图片描述

  • 操作1就是区间每个数减去自己的lowbit,由于a[i]是不超过int型范围的,所以操作1最多进行32次,可以单点暴力修改,同时记录这个区间是否都是0,用于剪枝

  • 操作2是区间每个数加上highbit,其实也就是最高位的贡献乘2,我们考虑把最高位与其他位分开维护区间和。 这样操作2就乘了区间乘某个数了,经典的线段树维护操作。

  • 具体要存的信息就是:
    1、二进制下最高位之和 ,涉及区间乘2
    2、其余位之和,涉及单点暴力修改
    3、区间是否都是0,用于剪枝,如果都是0,那么没必要进行操作1了
    4、区间乘2的懒标记

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
const int maxn=1e5+5;
const int mod = 998244353;
ll p2[maxn];
struct node 
{
   
    ll sum2;//维护最高位构成的序列的区间和  区间更新是乘积形式
    ll sum;//出最高位外的区间和 单点修改
    bool have;
    int l,r;
    ll tag;//区间每个数乘tag
}tree[maxn<<2];
int n;
ll lowbit(ll x) 
{
   
    return x&(-x);
}
inline int lc(int rt) 
{
   
    return rt<<1;
}
inline int rc(int rt) 
{
   
    return rt<<1|1;
}
inline void pushup(int rt) 
{
   
    tree[rt].sum2 = (tree[lc(rt)].sum2 + tree[rc(rt)].sum2)%mod;
    tree[rt].sum = (tree[lc(rt)].sum + tree[rc(rt)].sum)%mod;
    tree[rt].have = tree[lc(rt)].have | tree[rc(rt)].have;
}
inline ll find_h(ll x) 
{
   
    for(int i=30;i>=0;i--) 
    {
   
        if((1ll<<i) <= x) return (1ll<<i);
    }
}
inline void build(int rt,int l,int r) 
{
   
    tree[rt].tag=1;
    tree[rt].l=l,tree[rt].r=r;
    if(l == r) 
    {
   
        int v;
        cin>>v;
        tree[rt].sum2=find_h(v*1ll);
        tree[rt].sum=v-tree[rt].sum2;
        tree[rt].have=1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值