首页 > 其他分享 >[模板]zkw线段树

[模板]zkw线段树

时间:2022-10-04 19:48:13浏览次数:91  
标签:ch val int res 线段 bit zkw ll 模板

讲解在这里

[还有一个](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;
}

 

标签:ch,val,int,res,线段,bit,zkw,ll,模板
From: https://www.cnblogs.com/Catherine2006/p/16754281.html

相关文章

  • 「CF1455G」Forbidden Value 题解 (DP,线段树合并)
    题目简介已知初始值\(x=0\),给定下面\(2\)种命令:set\(y\)\(v\),令\(x=y\),或花费\(v\)元钱删除该命令;if\(y\)...end,如果\(x==y\),执行if...end中的命令,否则跳......
  • 李超线段树
    李超发明的一种维护平面上有限值域的直线或线段纵坐标大小的一种数据结构。因为是根据线段树研发的,代码也基于线段树,所以叫李超线段树。常规支持:插入一条线段或直线。......
  • P5431 【模板】乘法逆元 2
    1#include<bits/stdc++.h>2usingnamespacestd;3typedeflonglongll;4constintN=5e6+10;5llfac[N],sv[N],inv[N],a[N];6lln,p,k;7v......
  • ToroiseGit/GitBash 设置提交信息模板设置
    导航:一、背景二、ToroiseGit实施方案:三、GitBash实施方案 一、背景:当使用git提交代码时,每次的提交信息固定,却又比较长不好记的时,还需要将模板的地址保存下来,如果能设置......
  • 元模板 笔记
    对类型编写,由于c++不存在if(type==xxx){}这种语法。类型计算可以使用:1,重载。2,虚函数。继承。3,c语言中利用Union查看代码structVariant{union{......
  • Modular int模板
    防止一切因为忘记模数而导致爆0的事情发生!template<intmod>structmint{unsignedint_v;mint():_v(0){}template<classT>mint(Tv){......
  • Latex 如何写算法?推荐模板
    之前我已经在​​这篇文章​​总结了现有的算法包的区别。如果有选择苦难症的朋友可以考虑无脑使用以下模板来写算法。\usepackage[noend]{algpseudocode}#noend表示算法......
  • 吉司机线段树
    luoguP6242线段树3蒟蒻的代码//线段树3//需要支持的操作://修改:区间加,区间取min,区间求和//查询:区间最大值,区间历史最大值//瓶颈在于区间取min//引入区间最大......
  • 驱动开发:应用DeviceIoContro开发模板
    内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的......
  • 驱动开发:应用DeviceIoContro开发模板
    内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典......