首页 > 其他分享 >用线段树来接树状数组类的问题

用线段树来接树状数组类的问题

时间:2023-11-05 21:13:30浏览次数:33  
标签:树状 int 线段 mid ST 树来 ans query

大致解决的问题就是区间查询以及单点的修改
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int a[N],tag[N<<2];
struct{
	struct{
		int l,r,sum;
	}tr[N<<2];
	
	void push_up(int i){
		tr[i].sum = tr[i<<1].sum+tr[i<<1|1].sum;
	}
	void build(int i,int l,int r){
		tr[i].l= l;
		tr[i].r= r;
		if(l==r){
			tr[i].sum = a[l];
			return;
		}
		int mid=(l+r)>>1;
		build(i<<1,l,mid);
		build(i<<1|1,mid+1,r);
		push_up(i);
	}
	void add(int i,int l,int r,int k){
	    tag[i]+=k;
	    tr[i].sum+=(r-l+1)*k;
	}
	void push_down(int i,int l,int r){
		if(tag[i]){
			int mid=(l+r)>>1;
			add(i<<1,l,mid,tag[i]);
			add(i<<1|1,mid+1,r,tag[i]);
			tag[i]=0;
		}
	}
	void updata(int i,int l,int r,int L,int R,int k){
		if(L>=l&&R<=r){
			add(i,L,R,k);
			return;
		}
		push_down(i,L,R);
		int mid=(L+R)>>1;
		if(l<=mid){
			updata(i<<1,l,r,L,mid,k);
		}
		if(r>mid){
			updata(i<<1|1,l,r,mid+1,R,k);
		}
		push_up(i);
	}
	int query(int i,int l,int r,int L,int R){
		if(l<=L&&r>=R){
			return tr[i].sum;
		}
		push_down(i,L,R);
		int ans=0;
		int mid=(L+R)>>1;
	    if(l<=mid)ans+=query(i<<1,l,r,L,mid);
	    if(r>=mid+1)ans+=query(i<<1|1,l,r,mid+1,R);
	    return ans;
	}
}ST;
signed main(){
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	ST.build(1,1,n);
	for(int i=1;i<=q;i++){
		int x;
		cin>>x;
		if(x==1){
			int y,z,k;
			cin>>y>>z>>k;
			ST.updata(1,y,z,1,n,k);
		}else{
			int y;
			cin>>y;
			int ans=ST.query(1,y,y,1,n);
			cout<<ans<<"\n";
		}
	}
	return 0;
} 

标签:树状,int,线段,mid,ST,树来,ans,query
From: https://www.cnblogs.com/yufan1102/p/17811190.html

相关文章

  • 向量点乘判断点是否在线段上
    几种要考虑的情况1)点p和线段断点a,b重叠,pa•ab=pa.x*pa.y+ab.x*ab.y=02) pa,pb共线,则pa×pb=02-1)p在线段ab上,此时pa,pb的夹角为180度,cos(180)=-1,pa•ab=-|pa|*|ab|2-2)p在线段ab外,此时pa,pb的夹角为0度,cos(0)=1,pa•ab=|pa|*|ab|4)pa,pb不共线,cos(钝角)<0,cos(......
  • 点到线段的距离2
    几种要考虑的情况1)点和线段两端重叠的情况2)点在线段两侧的情况  p在另一侧的情况以此类推3)点在线段中间的情况   //点到线段的距离publicstaticfloatPointToSegmentDistance2(Vector2p,Vector2a,Vector2b){//点和线段端点重合varap=p......
  • 树状数组用线段树来写
    #include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintN=5e5+10;inta[N],tag[N<<2];struct{ struct{ intl,r,sum; }tr[N<<2]; voidpush_up(inti){ tr[i].sum=tr[i<<1].sum+tr[i<<1|1].sum; } voidbuild(inti......
  • F. Unique Occurrences(线段树分治+可撤销并查集)
    F.UniqueOccurrences假如我们删除所有权值为x的边,那么所有权值为x的边对答案的贡献就是\(\sumsz[u]*sz[v]\)sz表示两个联通块的大小,且(u,v)的边权为x我们可以用可撤销并查集来进行处理,简单来说就是将一条边的存在时间看作区间,然后挂到线段树上,然后遍历到每个叶子的时候进行......
  • vxe-table树状表格的实现(v3.5.9)
    这段时间改造了一个报表,需要在之前的基础上添加一个分类的维度,之前的报表样子找不到了,应该是用a-table写的普通表格,现在前端表格统一转到vxe-table上去了,记录一下开发树形表格过程中的坑。<vxe-tableborderid="xTable1"ref="xTable1"class="xTable1":column-con......
  • Opencascad(C++)-建模-创建有界直线段
    文章目录1、前言2、用gp_Lin创建一条直线2.1gp_Lin类成员函数2.2创建一条直线2.3运行结果3、创建一条有界的直线段3.1功能说明3.2函数说明3.2创建直线段的代码3.3测试效果1、前言在Opencascad开发时,经常会遇到创建直线的情况,采用gp_Line创建的直线段是无界的,如果想创建......
  • 线段树二分
    修改操作可以很简单的在线段树上打标记即可。常规做法直接二分R然后区间查询gcd,复杂度是仨log。upded:其实也是俩log,线段树查询区间gcd是单log。注意到你会将区间拆分成log个子区间,直接查询他们的gcd即可,直接查询为什么不会多乘个log呢。注意到对两个数\(x,y\)做......
  • 可持久化线段树学习笔记
    可持久化线段树前置知识:动态开点线段树基本介绍可持久化线段树可以维护多个版本信息。举个例子:你需要维护这样的一个长度为\(N\(1\len\le10^6)\)的数组,支持如下几种操作在某个历史版本上修改某一个位置上的值访问某个历史版本上的某一位置的值每次操作后生成一......
  • 第 116 场双周赛(双指针,背包问题,线段树+lz标记)
     本题为双指针和贪心。当我们遇到奇数个0或1时,直接将下一位改变即可。classSolution{public:intminChanges(strings){intn=s.size();intres=0;intl=0,r=-1;while(r++<n-1){if(s[l]==s[r])......
  • 2021 CCPC桂林 B.A Plus B Problem (线段树)
    传送门线段树大模拟!。考验线段树功底的时候来了,作为队伍的史山选手,写这么史也是情有可原的。#include<bits/stdc++.h>usingll=longlong;constintINF=0x3f3f3f3f;constintN=1e6+10;typedefstd::pair<int,int>PII;#definelsu<<1#definersu<<1|......