树状数组模板
1:树状数组求和模板
给n个数a1,a2,a3,…,an。
支持q个操作:
-
1 x d
,修改ax=d。 -
2 x
,查询∑xi=1ai。
输入格式
第一行两个整数n,q(1≤n,q≤2×105)。
接下来一行n个整数a1,a2,…,an(1≤ai≤109)。
接下来q行,每行一个形如1 x d
或者2 x
的操作,保证1≤x≤n,1≤d≤109。
输出格式
对于每个查询,输出一行,表示答案。
样例输入
5 5
1 2 3 4 5
2 4
1 1 5
2 5
1 2 3
2 3
样例输出
10
19
11
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
ll a[300000],c[300000];
int lowbit(ll x)
{
return x&(-x);
}
void updata(int l_,ll r_)
{
while(l_ <= n)
{
c[l_] += r_;
l_ += lowbit(l_);
}
}
void query(int l_)
{
ll ans = 0;
while(l_ > 0)
{
ans += c[l_];
l_ -= lowbit(l_);
}
cout << ans << "
";
}
void solve()
{
//int n,m;
cin >> n >> m;
for(int i = 1;i <= n;i ++)
{
cin >> a[i];
updata(i,a[i]);
}
while(m--)
{
int op;
cin >> op;
if(op == 1)
{
int l;
ll r;
cin >> l >> r;
updata(l,r-a[l]);
a[l] = r;
}
else
{
int l;
cin >> l;
query(l);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
t = 1;
//cin >> t;
while(t--)
{
solve();
}
}
2:树状数组求逆序对模板
有 n 个数 a1,a2,…,an对于其中的两个数字 x,y如果满足 x 出现的位置在 y 出现的位置前面并且 x 比 y 大,则称 (x,y) 为数组 a的一个逆序对。请问数组 a 的逆序对一共有多少个?形式化的说,请求出有多少组 (i,j) 满足 i<j 并且 ai>aj。
输入格式
第一行一个整数 n。
接下来一行 n 个整数,a1,a2,…,an。
输出格式
一行一个数,表示答案。
样例输入
4
4 2 3 1
样例输出
5
样例解释
5 个逆序对分别为 (4,2),(4,3),(4,1),(2,1),(3,1)。
数据范围
对于 100%100% 的数据,保证 2≤n≤100000,1≤ai≤n 并且每个数字都只会出现一次。
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3e5;
int n;
ll a[N],d[N];
int lowbit(int x)
{
return x&(-x);
}
void updata(ll l,int r)
{
while(l <= n)
{
d[l] += r;
l += lowbit(l);
}
}
int query(ll l)
{
ll sum = 0;
while(l)
{
sum += d[l];
l -= lowbit(l);
}
return sum ;
}
void solve()
{
cin >> n;
for(int i = 1;i <= n;i ++)
{
cin >> a[i];
}
ll ans = 0;
for(int i = 1;i <= n;i ++)
{
ans += query(n)-query(a[i]);
updata(a[i],1);
}
cout << ans << "
";
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
t = 1;
while(t--)
{
solve();
}
}
3:树状数组二分模板
给n个数a1,a2,a3,…,an。
支持q个操作:
-
1 x d
,修改ax=d。 -
2 s
,查询最大的T(0≤T≤n)满足∑Ti=1ai≤s。
输入格式
第一行两个整数n,q(1≤n,q≤2×105)。
接下来一行n个整数a1,a2,…,an(1≤ai≤109)。
接下来q行,每行一个形如1 x d
或者2 s
的操作,保证1≤x≤n,1≤d≤109,1≤s≤1014。
输出格式
对于每个查询,输出一行,表示答案。
样例输入
5 5
1 2 3 4 5
2 6
2 5
1 1 100
2 10
2 1000
样例输出
3 2 0 5
点击查看代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 3e6; int n,m; ll a[N],c[N]; ll lowbit(ll x) { return x&(-x); } void updata(ll x,ll y) { while(x<=n) { c[x] += y; x += lowbit(x); } } ll query(ll x) { ll ans = 0; for(int j = 18;j >= 0;j--) { if(ans + (1 << j) <= n && c[ans + (1 << j)] <= x) { ans += (1<<j); x -= c[ans]; } } return ans; } void solve() { cin >> n >> m; for(int i = 1;i <= n;i ++) { cin >> a[i]; updata(i,a[i]); } while(m--) { ll op; cin >> op; if(op == 1) { ll x,y; cin >> x >> y; updata(x,y-a[x]); a[x] = y; } else { ll x; cin >> x; ll ans = query(x); cout << ans << " "; } } } int main() { ios::sync_with_stdio(false); cin.tie(0); int t; t = 1; while(t--) { solve(); } }
4:二维树状数组模板
给n×m个数a1,1,a1,2,a1,3,…,a1,m,…,an,m。
支持q个操作:
-
1 x y d
,修改ax,y=d。 -
2 x y
,查询∑xi=1∑yj=1ai,j。
输入格式
第一行三个整数n,m,q(1≤n,m≤500,q≤2×105)。
接下来n行每行m个整数a1,1,a1,2,…,a1,m,…,an,m(1≤ai,j≤109)。
接下来q行,每行一个形如1 x y d
或者2 x y
的操作,保证1≤x≤n,1≤y≤m,1≤d≤109。
输出格式
对于每个查询,输出一行,表示答案。
样例输入
2 3 5
1 1 4
5 1 4
2 2 3
1 1 1 4
2 1 3
1 2 3 10
2 2 3
样例输出
16
9
25
点击查看代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3;
int n,m,q;
ll a[N][N],c[N][N];
ll lowbit(ll x)
{
return x&(-x);
}
void updata(ll x,ll y,ll z)
{
ll w = y;
while(x<=n)
{
y = w;
while(y<=m)
{
c[x][y] += z;
y += lowbit(y);
}
x += lowbit(x);
}
}
ll query(ll x,ll y)
{
ll ans = 0,w = y;
while(x)
{
y = w;
while(y)
ans += c[x][y],y -= lowbit(y);
x -= lowbit(x);
}
return ans;
}
void solve()
{
cin >> n >> m >> q;
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
cin >> a[i][j],updata(i,j,a[i][j]);
}
while(q--)
{
ll op;
cin >> op;
if(op == 2)
{
ll x,y;
cin >> x >> y;
ll ans = query(x,y);
cout << ans << "
";
}
else
{
ll x,y,z;
cin >> x >> y >> z;
updata(x,y,z-a[x][y]);
a[x][y] = z;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
t = 1;
while(t--)
{
solve();
}
}
推荐博客
https://www.cnblogs.com/Last--Whisper/p/13823614.html
原文地址:https://www.cnblogs.com/ljm-xiada/p/17441168.html