[模板]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;
}

 

posted @ 2022-10-04 19:25  Catherine_leah  阅读(112)  评论(0编辑  收藏  举报
/* */