HDU7116 Lowbit(线段树)
目录
Description
有两种操作:
\(1 \ L\ R\):对于每个数 \(a[i]=a[i]+lowbit(a[i])\)
\(2 \ L\ R\):查询区间 \([L,R]\) 的值
State
\(1<=T<=20\)
\(1<=n<=10^{5}\)
\(1<=m<=10^5\)
\(1<=a[i]<=998244353\)
Input
1
5
1 2 3 4 5
5
2 2 4
1 1 3
2 2 4
1 1 5
2 4 5
Output
9
12
14
Solution
这道题目是我遇到过最神奇的问题了,不懂就问,不将 \(mod=998244353\) 置为 \(cosnt\) 会 \(T\) 掉(求解释)
如果没有求余运算,思路其实挺好想的,当一个数的二进制形式 是这样时 \(1010101010...10\) ,它需要一步一步的加上对应的 \(lowbit\), 而一旦变为 \(2\) 的倍数,这个区间只需要 \(×2\) 就可以了
Code
const ll mod = 998244353;
const int N = 1e5 + 5;
ll n, m, _;
int i, j, k;
ll a[N];
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;
}
struct Node
{
int l, r;
ll sum, lazy;
bool tag;
#define lson id << 1
#define rson id << 1 | 1
void update(ll x)
{
sum = (sum * ksm(2, x)) % mod;
lazy = (x + lazy) % mod;
}
}t[N << 2];
void push_up(int id)
{
t[id].sum = (t[lson].sum + t[rson].sum) % mod;
t[id].tag = (t[lson].tag && t[rson].tag);
}
void push_down(int id)
{
ll 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].sum = t[id].lazy = t[id].tag = 0;
if(l == r){
t[id].sum = a[l];
t[id].tag = (t[id].sum == lowbit(t[id].sum));
}
else{
int mid = l + r >> 1;
build(l, mid, lson);
build(mid + 1, r, rson);
push_up(id);
}
return void();
}
void update(int l, int r, int id)
{
int L = t[id].l, R = t[id].r;
if(L >= l && r >= R && t[id].tag){
return t[id].update(1), void();
}
if(L == R){
t[id].sum += lowbit(t[id].sum);
return t[id].tag = (t[id].sum == lowbit(t[id].sum)), void();
}
push_down(id);
int mid = L + R >> 1;
if(mid >= l) update(l, r, lson);
if(r >= mid + 1) update(l, 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].sum;
}
else{
int mid = L + R >> 1;
ll ans = 0;
push_down(id);
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;
}
}
signed main()
{
//IOS;
rush(){
sd(n);
rep(i, 1, n) sll(a[i]);
build(1, n, 1);
sd(m);
rep(i, 1, m){
int opt, l, r;
sddd(opt, l, r);
if(opt == 1){
update(l, r, 1);
}
else{
ll ans = query(l, r, 1);
pll(ans);
}
}
}
//PAUSE;
return 0;
}

浙公网安备 33010602011771号