被xgc吊打的第二天,Rose's simulate,线段树分治

本文介绍了一种使用线段树解决区间更新与查询问题的高效算法。通过构建线段树并存储区间操作,实现了对区间内元素的快速更新与查询。讨论了如何将区间操作转化为断点处理,以及在查询时如何快速定位并合并相关区间。

正题

      原题是清华集训2014的玄学。

      因为对于i到j操作进行询问,所以考虑对操作建一棵线段树,每一个点存有一些区间,对于每一个点,这些区间的并为[1,n],每个区间存有两个值(a,b),对于这个区间内的每一个数k,表示经过我所管理的线段树操作后,会变成ax+b

      可以把这些区间转化成多个断点,每次加入一个询问操作会多两个断点,对于线段树上的一条链贡献,所以断点个数总和不超过O(m\log m),但是遍历一条链,加断点的时间复杂度是不正确的,考虑一棵线段树的子树,当且仅当它满的时候,才把左右儿子进行合并,因为之前不可能访问到线段树中的这个节点。

      合并两个端点可以直接过一遍,复杂度跟断点个数相关,所以插入时间复杂度还是O(m \log m)

      查询的时候,在线段树上找到对应的节点,二分找到对应的(a,b),把它们合并即可。

#include<bits/stdc++.h>
#define ls now<<1
#define rs now<<1|1
using namespace std;

const int N=100010;
int T,n,mod,m,t=0;
int A[N];

struct node{
	int l,r,a,b;
	node operator+(const node q)const {return (node){0,0,1ll*a*q.a%mod,(1ll*b*q.a%mod+q.b)%mod};}
}X;
vector<node> tr[N*10];

void calc(int &a,int &b,int c,int d){
	a=1ll*a*c%mod,b=1ll*c*b%mod+d;
	b>=mod?b-=mod:0;
}

void upload(int now){
	int a,b,l=0;
	for(int i=0,j=0;i<tr[ls].size() && j<tr[rs].size();){
		a=tr[ls][i].a;b=tr[ls][i].b;
		calc(a,b,tr[rs][j].a,tr[rs][j].b);
		if(tr[ls][i].r<=tr[rs][j].r){
			tr[now].push_back((node){l+1,tr[ls][i].r,a,b});
			l=tr[ls][i].r;
			if(tr[ls][i].r==tr[rs][j].r) i++,j++;
			else i++;
		}
		else tr[now].push_back((node){l+1,tr[rs][j].r,a,b}),l=tr[rs][j].r,j++;
	}
}

bool insert(int now,int x,int l,int r,node F){
	if(l==r){
		if(F.l>1) tr[now].push_back((node){1,F.l-1,1,0});
		tr[now].push_back(F);
		if(F.r<n) tr[now].push_back((node){F.r+1,n,1,0});
		return true;
	}
	int mid=(l+r)/2;
	if(x<=mid) {insert(ls,x,l,mid,F);return false;}
	else if(insert(rs,x,mid+1,r,F)) {upload(now);return true;}
	else return false;
}

node get_ans(int now,int x,int y,int k,int l,int r){
	if(x==l && y==r){
		int l=0,r=tr[now].size()-1;
		while(l<=r){
			int mid=(l+r)/2;
			if(tr[now][mid].r<k) l=mid+1;
			else if(tr[now][mid].l<=k && k<=tr[now][mid].r) return tr[now][mid];
			else r=mid-1;
		}
	}
	int mid=(l+r)/2;
	if(y<=mid) return get_ans(ls,x,y,k,l,mid);
	else if(mid<x) return get_ans(rs,x,y,k,mid+1,r);
	else return get_ans(ls,x,mid,k,l,mid)+get_ans(rs,mid+1,y,k,mid+1,r);
}

int main(){
	scanf("%d %d %d",&T,&n,&mod);T=T&1;
	for(int i=1;i<=n;i++) scanf("%d",&A[i]);
	scanf("%d",&m);
	int tot=m;
	int type,x,y,a,b;
	long long last=0;
	while(m--){
		scanf("%d %d %d %d",&type,&x,&y,&a);
		if(T) x^=last,y^=last; 
		if(!type){
			scanf("%d",&b);
			t++;insert(1,t,1,tot,(node){x,y,a,b});
		}
		else{
			if(T) a^=last;
			X=get_ans(1,x,y,a,1,tot);
			printf("%lld\n",last=(1ll*A[a]*X.a%mod+X.b)%mod);
		}
	}
}

 

【最优潮流】直流最优潮流(OPF)课设(Matlab代码实现)内容概要:本文档主要围绕“直流最优潮流(OPF)课设”的Matlab代码实现展开,属于电力系统优化领域的教学与科研实践内容。文档介绍了通过Matlab进行电力系统最优潮流计算的基本原理与编程实现方法,重点聚焦于直流最优潮流模型的构建与求解过程,适用于课程设计或科研入门实践。文中提及使用YALMIP等优化工具包进行建模,并提供了相关资源下载链接,便于读者复现与学习。此外,文档还列举了大量与电力系统、智能优化算法、机器学习、路径规划等相关的Matlab仿真案例,体现出其服务于科研仿真辅导的综合性平台性质。; 适合人群:电气工程、自动化、电力系统及相关专业的本科生、研究生,以及从事电力系统优化、智能算法应用研究的科研人员。; 使用场景及目标:①掌握直流最优潮流的基本原理与Matlab实现方法;②完成课程设计或科研项目中的电力系统优化任务;③借助提供的丰富案例资源,拓展在智能优化、状态估计、微电网调度等方向的研究思路与技术手段。; 阅读建议:建议读者结合文档中提供的网盘资源,下载完整代码与工具包,边学习理论边动手实践。重点关注YALMIP工具的使用方法,并通过复现文中提到的多个案例,加深对电力系统优化问题建模与求解的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值