首页 > 其他分享 >高级数据结构--树状数组

高级数据结构--树状数组

时间:2023-10-03 17:56:47浏览次数:37  
标签:10 return 树状 -- nullptr cin int add 数据结构

一维树状数组

单点修改-区间查询

输入

3 2
1 2 3
1 2 0
2 1 3

输出

6

数据范围

对于所有数据,\(1≤n,q≤10^6,∣a[i]∣≤10^6, 1≤l≤r≤n, ∣x∣≤10^6\)。

点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define int long long

using namespace std;

const int N = 1e6 + 10;

int a[N], tr[N];
int n, m;

int lowbit(int x)
{
	return x & -x;
}

void add(int x, int y)
{
	for(int i = x; i <= n; i += lowbit(i))
		tr[i] += y;
}

int sum(int x)
{
	int ans = 0;
	for(int i = x; i; i -= lowbit(i))
		ans += tr[i];
	return ans;
}

int query(int l, int r)
{
	return sum(r) - sum(l - 1);
}

void solve()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)
		cin >> a[i];
		
	for(int i = 1; i <= n; i ++)
		add(i, a[i]);
	int f, l, r;
	while(m --)
	{
		cin >> f >> l >> r;
		if(f == 1)
			add(l, r);
		else
			cout << query(l, r) << endl;
	}
}

signed main()
{
	IOS;
	int _ = 1;
	// cin >> _;
	while(_ --)
		solve();
	return 0;
}

区间修改-单点查询

输入

3 2
1 2 3
1 1 3 0
2 2

输出

2

数据范围

对于所有数据,\(1≤n,q≤10^6 , ∣a[i]∣≤10^6 , 1≤l≤r≤n, ∣x∣≤10^6\)。

点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define int long long

using namespace std;

const int N = 1e6 + 10;

int a[N], tr[N];
int n, m;

int lowbit(int x)
{
	return x & -x;
}

void add(int x, int y)
{
	for(int i = x; i <= n; i += lowbit(i))
		tr[i] += y;
}

int sum(int x)
{
	int ans = 0;
	for(int i = x; i; i -= lowbit(i))
		ans += tr[i];
	return ans;
}

void solve()
{
	cin >> n >> m;
	
	for(int i = 1; i <= n; i ++)
		cin >> a[i];
	
	for(int i = 1; i <= n; i ++)
		add(i, a[i] - a[i - 1]);
	
	int f, l, r, x;
	while(m --)
	{
		cin >> f;
		if(f == 1)
		{
			cin >> l >> r >> x;
			add(l, x), add(r + 1, -x);
		}
		else
		{
			cin >> l;
			cout << sum(l) << '\n';
		}
	}
}

signed main()
{
	IOS;
	int _ = 1;
	// cin >> _;
	while(_ --)
		solve();
	return 0;
}

区间修改-区间查询

输入

5 10
2 6 6 1 1
2 1 4
1 2 5 10
2 1 3
2 2 3
1 2 2 8
1 2 3 7
1 4 4 10
2 1 2
1 4 5 6
2 3 4

输出

15
34
32
33
50

数据范围

对于所有数据,$1≤n,q≤10^6 , ∣a[i]∣≤10^6 , 1≤l≤r≤n, ∣x∣≤10^6 $。

点击查看代码
#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr);
#define int long long

using namespace std;

const int N = 1e6 + 10;

int a[N];
int tr[N], pretr[N];
int n, m;

int lowbit(int x)
{
	return x & -x;
}

void add(int tr[], int x, int y)
{
	for(int i = x; i <= n; i += lowbit(i))
		tr[i] += y;
}

int sum(int tr[], int x)
{
	int ans = 0;
	for(int i = x; i; i -= lowbit(i))
		ans += tr[i];
	return ans;
}

int ask(int x)
{
	return sum(tr, x) * (x + 1) - sum(pretr, x);
}

void solve()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i ++)
		cin >> a[i];
	
	for(int i = 1; i <= n; i ++)
	{
		int x = a[i] - a[i - 1];
		add(tr, i, x);
		add(pretr, i, x * i);
	}

	int l, r, x, f;
	while(m --)
	{
		cin >> f >> l >> r;
		if(f == 1)
		{
			cin >> x;
			add(tr, l, x);
			add(tr, r + 1, -x);
			add(pretr, l, l * x);
			add(pretr, r + 1, (r + 1) * (-x));
		}
		else
		{
			printf("%lld\n", ask(r) - ask(l - 1));
		}
	}
}

signed main()
{
	IOS;
	int _ = 1;
	// cin >> _;
	while(_ --)
		solve();
	return 0;
}

二维树状数组

单点修改-区间查询

输入

2 2
1 1 1 3
1 2 2 4
2 1 1 2 2

输出

7

数据范围

对于 10% 的数据,n=1;
对于另10% 的数据,m=1;
对于全部数据,\(1≤n,m≤2^{12} ,1≤x,a,c≤n,1≤y,b,d≤m,∣k∣≤10^5\),保证操作数目不超过 \(3×10^5\) ,且询问的子矩阵存在。

点击查看代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr)
#define int long long

using namespace std;

const int N = 5010;

int tr[N][N];
int n, m;

int lowbit(int x)
{
    return x & -x;
}

void get(int x, int y, int k)
{
    for(int i = x; i <= n; i += lowbit(i))
        for(int j = y; j <= m; j += lowbit(j))
            tr[i][j] += k;
}

int sum(int x, int y)
{
    int ans = 0;
    for(int i = x; i; i -= lowbit(i))
        for(int j = y; j; j -= lowbit(y))
            ans += tr[i][j];
    return ans;
}

int query(int x1, int y1, int x2, int y2)
{
    return sum(x2, y2) - sum(x2, y1 - 1) - sum(x1 - 1, y2) + sum(x1 - 1, y1 - 1);
}

void solve()
{
    int x1, y1, x2, y2;
    int x, y, k;
    int f;
    x1 = y1 = x2 = y2 = x = y = k = f = 0;
    cin >> n >> m;
    while(cin >> f)
    {
        if(f == 1)
        {
            cin >> x >> y >> k;
            get(x, y, k);
        }
        else
        {
            cin >> x1 >>  y1 >> x2 >> y2;
            cout << query(x1, y1, x2, y2) << '\n';
        }
    }
}

signed main()
{
    IOS;
    int _ = 1;
    // cin >> _;
    while(_ --)
        solve();
    return _ ^ _;
}

区间修改-区间查询

输入

4 4
1 1 1 3 3 2
1 2 2 4 4 1
2 2 2 3 3

输出

12

数据范围

对于 10% 的数据,1≤n,m≤16,操作不超过 200 个;
对于 60% 的数据,1≤n,m≤512;
对于 100% 的数据,\(1≤n,m≤2048,∣x∣≤500\),操作不超过 \(2×10^5\)个,保证运算过程中及最终结果均不超过 64 位带符号整数类型的表示范围,并且修改与查询的子矩阵存在。

点击查看代码
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr),cout.tie(nullptr)
#define int long long

using namespace std;

const int N = 2100;

int tr1[N][N], tr2[N][N], tr3[N][N], tr4[N][N];
int n, m;

int lowbit(int x)
{
    return x & -x;
}

void add(int x, int y, int d)
{
    for(int i = x; i <= n; i += lowbit(i))
        for(int j = y; j <= m; j += lowbit(j))
        {
        	tr1[i][j] += d;
        	tr2[i][j] += x * d;
        	tr3[i][j] += y * d;
        	tr4[i][j] += x * y * d;
        }
}

int sum(int x, int y)
{
    int ans = 0;
    for(int i = x; i; i -= lowbit(i))
        for(int j = y; j; j -= lowbit(j))
        	ans += (x + 1) * (y + 1) * tr1[i][j] - (x + 1) * tr3[i][j] - (y + 1) * tr2[i][j] + tr4[i][j];
    return ans;
}

int query(int x1, int y1, int x2, int y2)
{
    return sum(x2, y2) - sum(x2, y1 - 1) - sum(x1 - 1, y2) + sum(x1 - 1, y1 - 1);
}

void get(int x1, int y1, int x2, int y2, int x)
{
	add(x1, y1, x);
    add(x1, y2 + 1, -x);
    add(x2 + 1, y1, -x);
    add(x2 + 1, y2 + 1, x);
}

void solve()
{
    int x1, y1, x2, y2;
    int x, y, k;
    int f;
    x1 = y1 = x2 = y2 = x = y = k = f = 0;
    cin >> n >> m;
    while(cin >> f)
    {
        if(f == 1)
        {
            cin >> x1 >> y1 >> x2 >> y2 >> k;
            get(x1, y1, x2, y2, k);
        }
        else
        {
            cin >> x1 >> y1 >> x2 >> y2;
            cout << query(x1, y1, x2, y2) << '\n';
        }
    }
}

signed main()
{
    IOS;
    int _ = 1;
    // cin >> _;
    while(_ --)
        solve();
    return _ ^ _;
}

标签:10,return,树状,--,nullptr,cin,int,add,数据结构
From: https://www.cnblogs.com/chfychin/p/17741397.html

相关文章

  • Java中的对象到底是什么
    对象是现实世界中的一切物体(实体,或能够定义的东西)Smalltalk是第一个成功的面向对象的语言在编程世界中,对象通过类来实例化;同一个类型的对象可以接受相同的消息状态+行为+标识=对象每个对象在内存中都会有一个唯一的地址。对象学习内容:组合,继承,多态,封装。类和对象类和对象时......
  • socket,tcp,http三者之间的区别和原理
    socket,tcp,http三者之间的区别和原理http、TCP/IP协议与socket之间的区别下面的图表试图显示不同的TCP/IP和其他的协议在最初OSI模型中的位置:7   应用层   例如HTTP、SMTP、SNMP、FTP、Telnet、SIP、SSH、NFS、RTSP、XMPP、Whois、ENRP6   表示层   例如XDR、ASN.1......
  • 微服务17:微服务治理之异常驱逐
    ★微服务系列微服务1:微服务及其演进史微服务2:微服务全景架构微服务3:微服务拆分策略微服务4:服务注册与发现微服务5:服务注册与发现(实践篇)微服务6:通信之网关微服务7:通信之RPC微服务8:通信之RPC实践篇(附源码)微服务9:服务治理来保证高可用微服务10:系统服务熔断、限流微服务11......
  • webpack打包丢失样式的问题
    背景在我部署好代码后,另一个同事就去访问页面查看,结果发现样式有问题,问我是不是代码没更新到?我反复去看了下时间和文件,证明代码是最新的了。但后来对比了下页面和本地的样式,发现确实跟本地代码对不上。分析过程一开始还以为是部署的代码有问题,就到服务器查看,确实是丢失了样式......
  • 几道 ARC 的题目
    写在前面的话我从今年\(7\)月末开始断断续续地写ARC的题目,\(9\)月中旬的时候已经做了少量的题了,还有许多F没写,一方面是因为我水平太差看不懂题解,另一方面是因为一种题写多了总是有一种无聊的感觉的。所以到此为止吧,把这些日子水的题放在这篇博客中吧,以后再写ARC的题大概......
  • FreeRTOS 原理 --- 任务通知
    简介任务通知核心包含是一个32位的无符号整数和一个8位的通知状态,这两个在任务控制块中,通知任务就是一个任务或者中断改写另外一个任务中的32位的无符号整数,改写这个整数的方式可以有所不同可以让这个整数加1,模拟信号量设置该整数的指定的某些位,模拟事件组直接选择覆盖或者不......
  • vue 数据data-uniapp
    data属性data必须声明为返回一个初始数据对象的函数(注意函数内返回的数据对象不要直接引用函数外的对象);否则页面关闭时,数据不会自动销毁,再次打开该页面时,会显示上次数据。 //正确用法,使用函数返回对象 data(){ return{ title:'Hello' } } //错误写法,会导致再次......
  • 在linux服务器上安装scvi后无法调用GPU
    问题描述:WARNING-NoGPU/TPUfound,fallingbacktoCPU.(SetTF_CPP_MIN_LOG_LEVEL=0andrerunformoreinfo.) 解决方案: 测试如下代码,如果为True则执行第二步。importtorchprint(torch.cuda.is_available())测试如下代码importjaxprint(jax.devices......
  • 4.循环机构习题
    1.【例4.1】for循环求和【题目描述】利用for循环。计算输出1+2+3+...+n的和。【输入】输入n。【输出】如题述,之和。【输入样例】10【输出样例】55【提示】【数据规模及约定】对于100%的数据,1≤n≤100。i=1n=int(input())sun=0foriinrange(n+1):sun=......
  • vue2 指令- unaipp
    指令指令是有v-前缀的特殊属性。指令属性的值预期是单个JavaScript表达式(v-for是例外情况)。指令的作用是,当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM。一些指令能够接收一个“参数”,在指令名称之后以冒号(:)表示。v-bind动态地绑定一个或多个属性,或......