[模板]zkw线段树
[还有一个](https://wenku.baidu.com/view/f27db60ee87101f69e319544.html)
A. 数列操作
单点修改,区间查询
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 2;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, m;
ll a[maxn<<2], mark[maxn<<2], bit, lb, ans;
char s[5];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
inline int getlong(int k)
{
int i = 0;
while(k >>= 1) i++;
return i;
}
inline void update(int s, ll val)
{
s = bit + s;
a[s] += val;
while(s >>= 1)
{
a[s] = a[s<<1] + a[s<<1|1];
}
}
inline ll ask(int k)
{
ll tmp = 1<<(lb-getlong(k));
ll res = a[k] + mark[k]*tmp;
while(k >>= 1)
{
res += mark[k]*tmp;
}
return res;
}
inline ll query(int s, int t)
{
ll res = 0;
for(s=s+bit-1,t=t+bit+1; s^t^1; s>>=1,t>>=1)
{
if(!(s&1)) res += ask(s^1);
if(t&1) res += ask(t^1);
}
return res;
}
int main()
{
n = read();
for(bit=1; bit-2<n; bit<<=1);
lb = getlong(bit);
for(int i=bit+1; i<=bit+n; i++) a[i] = read();
for(int i=bit-1; i; i--)
{
a[i] = a[i<<1] + a[i<<1|1];
}
m = read();
while(m--)
{
scanf("%s", s);
if(s[0] == 'S')
{
int l = read(), r = read();
ans = query(l, r);
printf("%lld\n", ans);
}
else
{
int pos = read(), val = read();
update(pos, val);
}
}
return 0;
}
B. 数列操作b
区间修改,单点查询
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 2;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, m;
ll a[maxn<<2], mark[maxn<<2], bit, lb, ans;
char s[6];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
inline int getlong(int k)
{
int i = 0;
while(k >>= 1) i++;
return i;
}
inline void add(int k, ll t)
{
ll tmp = 1<<(lb-getlong(k));
while(k >>= 1)
{
a[k] += t*tmp;
}
}
inline void update(int s, int t, ll val)
{
for(s=s+bit-1,t=t+bit+1; s^t^1; s>>=1,t>>=1)
{
if(!(s&1)) {mark[s^1] += val; add(s^1, val);}
if(t&1) {mark[t^1] += val; add(t^1, val);}
}
}
inline ll query(int k)
{
k = bit + k;
ll tmp = 1<<(lb-getlong(k));
ll res = a[k] + mark[k]*tmp;
while(k >>= 1)
{
res += mark[k]*tmp;
}
return res;
}
int main()
{
n = read();
for(bit=1; bit-2<n; bit<<=1);
lb = getlong(bit);
for(int i=bit+1; i<=bit+n; i++) a[i] = read();
for(int i=bit-1; i; i--)
{
a[i] = a[i<<1] + a[i<<1|1];
}
m = read();
while(m--)
{
scanf("%s", s);
if(s[0] == 'Q')
{
int pos = read();
ans = query(pos);
printf("%lld\n", ans);
}
else
{
int l = read(), r = read(), val = read();
update(l, r, val);
}
}
return 0;
}
C. 数列操作c
区间修改,区间查询
code
//正青春的年华,就是应该献给直指星辰的梦想啊!
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 2;
const ll mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, m;
ll a[maxn<<2], mark[maxn<<2], bit, lb, ans;
char s[5];
inline int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
{
f = -1;
}
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
return x * f;
}
inline int getlong(int k)
{
int i = 0;
while(k >>= 1) i++;
return i;
}
inline void add(int k, ll t)
{
ll tmp = 1<<(lb-getlong(k));
while(k >>= 1)
{
a[k] += t*tmp;
}
}
inline void update(int s, int t, ll val)
{
for(s=s+bit-1,t=t+bit+1; s^t^1; s>>=1,t>>=1)
{
if(!(s&1)) {mark[s^1] += val; add(s^1, val);}
if(t&1) {mark[t^1] += val; add(t^1, val);}
}
}
inline ll ask(int k)
{
ll tmp = 1<<(lb-getlong(k));
ll res = a[k] + mark[k]*tmp;
while(k >>= 1)
{
res += mark[k]*tmp;
}
return res;
}
inline ll query(int s, int t)
{
ll res = 0;
for(s=s+bit-1,t=t+bit+1; s^t^1; s>>=1,t>>=1)
{
if(!(s&1)) res += ask(s^1);
if(t&1) res += ask(t^1);
}
return res;
}
int main()
{
n = read();
for(bit=1; bit-2<n; bit<<=1);
lb = getlong(bit);
for(int i=bit+1; i<=bit+n; i++) a[i] = read();
for(int i=bit-1; i; i--)
{
a[i] = a[i<<1] + a[i<<1|1];
}
m = read();
while(m--)
{
scanf("%s", s);
if(s[0] == 'S')
{
int l = read(), r = read();
ans = query(l, r);
printf("%lld\n", ans);
}
else
{
int l = read(), r = read(), val = read();
update(l, r, val);
}
}
return 0;
}
时光花火,水月星辰