树状数组、线段树板子

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define ll long long
using namespace std;
const int maxx=100001;
int n,q;
ll c1[maxx],c2[maxx];
ll lowbit(ll x){return x&(-x);}
struct tree{
	void add(long long *array,int x,int val){
		for(int i=x;i<=n;i+=lowbit(i))
			array[i]+=val;
	}
	long long query(long long *array,int x){
		long long ans=0;
		for(int i=x;i;i-=lowbit(i))
			ans+=array[i];
		return ans;
	}
}tree;
ll read(){
	char x;
	while((x=getchar())<'0' || x>'9');
	ll u=x-'0';
	while((x=getchar())>='0' && x<='9')u=u*10+x-'0';
	return u;
	}
int main(){
#ifndef ONLINE_JUDGE
	freopen("input.in","r",stdin);
	freopen("output.out","w",stdout);
#endif
	int i,j,k,m,pre=0;
	n=read();q=read();
	for(i=1;i<=n;i++){
		k=read();
		tree.add(c1,i,k-pre);
		tree.add(c2,i,(k-pre)*(i-1));
		pre=k;
	}
	while(q--){
		k=read();
		if(k==1){
			i=read();
			j=read();
			m=read();
			tree.add(c1,i,m);
			tree.add(c1,j+1,-m);
			tree.add(c2,i,m*(i-1));
			tree.add(c2,j+1,-m*j);
		}
		else{
			i=read();
			j=read();
			ll dog=j*tree.query(c1,j)-tree.query(c2,j);
			ll sb=(i-1)*tree.query(c1,i-1)-tree.query(c2,i-1);
			printf("%lld\n",dog-sb);
		}
	}
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>

#define ls node << 1
#define rs node << 1 | 1
#define maxn 100005
#define For(a, b, c) for(a = b; a <= (int)c; ++a)
using namespace std;
typedef long long LL;
int n, m;
LL tr[maxn << 2], plu[maxn << 2], mut[maxn << 2], p, a[maxn];

inline void push_up(int node){
	tr[node] = (tr[ls] + tr[rs]) % p;
}

void build(int node, int l, int r){
	mut[node] = 1;
	if(l == r){
		tr[node] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	push_up(node);
}

inline void add(int node, int l, int r, int x, bool d){
	if(!d){
		(mut[node] *= x) %= p;
		(tr[node] *= x) %= p;
		(plu[node] *= x) %= p;
	}
	else{
		(plu[node] += x) %= p;
		(tr[node] += (r - l + 1) * x) %= p;
	}
}

inline void push_down(int node, int l, int r){
	if(mut[node] == 1 && !plu[node]) return ;
	int mid = l + r >> 1;
	if(mut[node] != 1){
		(tr[ls] *= mut[node]) %= p;
		(mut[ls] *= mut[node]) %= p;
		(plu[ls] *= mut[node]) %= p;
		(tr[rs] *= mut[node]) %= p;
		(mut[rs] *= mut[node]) %= p;
		(plu[rs] *= mut[node]) %= p;
	} mut[node] = 1;
	if(plu[node]){
		(tr[ls] += (mid - l + 1) * plu[node]) %= p;
		(plu[ls] += plu[node]) %= p;
		(tr[rs] += (r - mid) * plu[node]) %= p;
		(plu[rs] += plu[node]) %= p;
	} plu[node] = 0;
}

void updata(int node, int l, int r, int z, int y, int x, bool d){
	if(l >= z && r <= y){
		add(node, l, r, x, d);
		return ;
	}
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) updata(ls, l, mid, z, y, x, d);
	else if(z > mid) updata(rs, mid + 1, r, z, y, x, d);
	else{
		updata(ls, l, mid, z, y, x, d);
		updata(rs, mid + 1, r, z, y, x, d);
	}
	push_up(node);
}

LL query(int node, int l, int r, int z, int y){
	if(l >= z && r <= y) return tr[node];
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) return query(ls, l, mid, z, y);
	else if(z > mid) return query(rs, mid + 1, r, z, y);
	return (query(ls, l, mid, z, y) + query(rs, mid + 1, r, z, y)) % p;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("st.in", "r", stdin);
	freopen("st.out","w",stdout);
#endif
	int i, u, x, y, k;
	scanf("%d%d%lld", &n, &m, &p);
	For(i, 1, n) scanf("%lld", &a[i]);
	build(1, 1, n);
	while(m--){
		scanf("%d", &u);
		if(u == 1){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 0);
		}
		else if(u == 2){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 1);
		}
		else{
			scanf("%d%d", &x, &y);
			printf("%lld\n", query(1, 1, n, x, y));
		}
	}
	return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>

#define ls node << 1
#define rs node << 1 | 1
#define maxn 100005
#define For(a, b, c) for(a = b; a <= (int)c; ++a)
using namespace std;
typedef long long LL;
int n, m;
LL tr[maxn << 2], plu[maxn << 2], mut[maxn << 2], p, a[maxn];

inline void push_up(int node){
	tr[node] = (tr[ls] + tr[rs]) % p;
}

void build(int node, int l, int r){
	mut[node] = 1;
	if(l == r){
		tr[node] = a[l];
		return ;
	}
	int mid = l + r >> 1;
	build(ls, l, mid);
	build(rs, mid + 1, r);
	push_up(node);
}

inline void add(int node, int l, int r, int x, bool d){
	if(!d){
		(mut[node] *= x) %= p;
		(tr[node] *= x) %= p;
		(plu[node] *= x) %= p;
	}
	else{
		(plu[node] += x) %= p;
		(tr[node] += (r - l + 1) * x) %= p;
	}
}

inline void push_down(int node, int l, int r){
	if(mut[node] == 1 && !plu[node]) return ;
	int mid = l + r >> 1;
	if(mut[node] != 1){
		(tr[ls] *= mut[node]) %= p;
		(mut[ls] *= mut[node]) %= p;
		(plu[ls] *= mut[node]) %= p;
		(tr[rs] *= mut[node]) %= p;
		(mut[rs] *= mut[node]) %= p;
		(plu[rs] *= mut[node]) %= p;
	} mut[node] = 1;
	if(plu[node]){
		(tr[ls] += (mid - l + 1) * plu[node]) %= p;
		(plu[ls] += plu[node]) %= p;
		(tr[rs] += (r - mid) * plu[node]) %= p;
		(plu[rs] += plu[node]) %= p;
	} plu[node] = 0;
}

void updata(int node, int l, int r, int z, int y, int x, bool d){
	if(l >= z && r <= y){
		add(node, l, r, x, d);
		return ;
	}
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) updata(ls, l, mid, z, y, x, d);
	else if(z > mid) updata(rs, mid + 1, r, z, y, x, d);
	else{
		updata(ls, l, mid, z, y, x, d);
		updata(rs, mid + 1, r, z, y, x, d);
	}
	push_up(node);
}

LL query(int node, int l, int r, int z, int y){
	if(l >= z && r <= y) return tr[node];
	push_down(node, l, r);
	int mid = l + r >> 1;
	if(y <= mid) return query(ls, l, mid, z, y);
	else if(z > mid) return query(rs, mid + 1, r, z, y);
	return (query(ls, l, mid, z, y) + query(rs, mid + 1, r, z, y)) % p;
}

int main(){
#ifndef ONLINE_JUDGE
	freopen("st.in", "r", stdin);
	freopen("st.out","w",stdout);
#endif
	int i, u, x, y, k;
	scanf("%d%d%lld", &n, &m, &p);
	For(i, 1, n) scanf("%lld", &a[i]);
	build(1, 1, n);
	while(m--){
		scanf("%d", &u);
		if(u == 1){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 0);
		}
		else if(u == 2){
			scanf("%d%d%d", &x, &y, &k);
			updata(1, 1, n, x, y, k, 1);
		}
		else{
			scanf("%d%d", &x, &y);
			printf("%lld\n", query(1, 1, n, x, y));
		}
	}
	return 0;
}

 

基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究(Matlab代码实现)内容概要:本文围绕“基于可靠性评估序贯蒙特卡洛模拟法的配电网可靠性评估研究”,介绍了利用Matlab代码实现配电网可靠性的仿真分析方法。重点采用序贯蒙特卡洛模拟法对配电网进行长时间段的状态抽样与统计,通过模拟系统元件的故障与修复过程,评估配电网的关键可靠性指标,如系统停电频率、停电持续时间、负荷点可靠性等。该方法能够有效处理复杂网络结构与设备时序特性,提升评估精度,适用于含分布式电源、电动汽车等新型负荷接入的现代配电网。文中提供了完整的Matlab实现代码与案例分析,便于复现和扩展应用。; 适合人群:具备电力系统基础知识和Matlab编程能力的高校研究生、科研人员及电力行业技术人员,尤其适合从事配电网规划、运行与可靠性分析相关工作的人员; 使用场景及目标:①掌握序贯蒙特卡洛模拟法在电力系统可靠性评估中的基本原理与实现流程;②学习如何通过Matlab构建配电网仿真模型并进行状态转移模拟;③应用于含新能源接入的复杂配电网可靠性定量评估与优化设计; 阅读建议:建议结合文中提供的Matlab代码逐段调试运行,理解状态抽样、故障判断、修复逻辑及指标统计的具体实现方式,同时可扩展至不同网络结构或加入更多不确定性因素进行深化研究。
### 树状数组线段树的实现及应用 #### 树状数组(Binary Indexed Tree, BIT) 树状数组是一种用于高效处理前缀和查询以及单点修改的数据结构。它的核心思想是通过一种特殊的存储方式,将前缀和的计算复杂度降低到 \(O(\log N)\)。树状数组的核心操作包括单点修改和区间查询。 - **lowbit运算**:树状数组的关键在于 `lowbit` 运算,它提取一个数的二进制表示中最低位的1及其后续的0所对应的值[^2]。例如,`lowbit(6)` 的结果为 2,因为 6 的二进制表示为 `110`。 - **单点修改**:当需要对某个位置上的数进行修改时,树状数组会沿着父节点路径更新所有相关的节点值。代码如下: ```python def update(index, val): while index <= n: tree[index] += val index += lowbit(index) ``` - **前缀和查询**:树状数组可以通过累积的方式快速求解前缀和。代码如下: ```python def get_sum(index): ans = 0 while index > 0: ans += tree[index] index -= lowbit(index) return ans ``` 树状数组的经典应用场景包括统计序列中在元素左边比该元素小的元素个数[^2],以及维护动态前缀和。 #### 线段树(Segment Tree) 线段树是一种更加通用的数据结构,它可以处理更复杂的区间操作,如区间修改、区间查询等。线段树的基本思想是将整个区间递归地划分为子区间,并用一棵二叉树来表示这些划分。 - **建树**:线段树的构建过程是一个递归过程,每个节点代表一个区间,叶子节点代表单个元素。代码如下: ```python def build_tree(node, start, end): if start == end: tree[node] = arr[start] else: mid = (start + end) // 2 build_tree(2 * node, start, mid) build_tree(2 * node + 1, mid + 1, end) tree[node] = tree[2 * node] + tree[2 * node + 1] ``` - **单点修改**:线段树支持单点修改操作,类似于树状数组的单点修改。代码如下: ```python def update_tree(node, start, end, idx, val): if start == end: arr[idx] = val tree[node] = val else: mid = (start + end) // 2 if start <= idx <= mid: update_tree(2 * node, start, mid, idx, val) else: update_tree(2 * node + 1, mid + 1, end, idx, val) tree[node] = tree[2 * node] + tree[2 * node + 1] ``` - **区间查询**:线段树可以高效地查询任意区间的和。代码如下: ```python def query_tree(node, start, end, l, r): if r < start or end < l: return 0 if l <= start and end <= r: return tree[node] mid = (start + end) // 2 p1 = query_tree(2 * node, start, mid, l, r) p2 = query_tree(2 * node + 1, mid + 1, end, l, r) return p1 + p2 ``` 线段树的应用场景非常广泛,包括但不限于区间最大值/最小值查询、区间和查询、区间修改等。此外,线段树还可以通过懒惰标记(Lazy Propagation)优化区间修改操作[^2]。 #### 树状数组线段树的比较 - **代码长度与效率**:相比于线段树树状数组的代码更短,效率更高,适合解决简单的前缀和问题[^1]。 - **功能灵活性**:线段树的功能更为强大,能够处理更复杂的区间操作,但其代码复杂度也更高[^1]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值