首页 > 其他分享 >树状数组用线段树来写

树状数组用线段树来写

时间:2023-11-03 20:35:32浏览次数:28  
标签:树状 int 线段 tr mid cin 树来 push sum

#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,线段,tr,mid,cin,树来,push,sum
From: https://www.cnblogs.com/yufan1102/p/17808387.html

相关文章

  • 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|......
  • 李超线段树
    P4097【模板】李超线段树/[HEOI2013]Segment强制在线,那么这种问题该如何解决?我们可以把任务转化为维护如下操作:加入一个一次函数给定\(k\),求定义域包含\(k\)的所有一次函数中,在\(k\)处取值最大的那个,如果有多个函数取值相同,选编号最小的。注意:有可能线段斜率不......
  • 可持久化线段树学习笔记
    主席树的定义主席树,也称可持久化线段树,什么是可持久化线段树呢,即为一颗记录了所有更新过程的线段树。能够处理出从第$i$次更新到第$j$次更新的线段树变化。前置知识值域线段树值域线段树的区间存的并不是节点信息,而是在值在某一范围内的数的个数。如图就是一棵值域线段树......
  • P5537 【XR-3】系统设计 题解-哈希+线段树二分
    20231026P5537【XR-3】系统设计题解-哈希+线段树二分这个东西怎么会和哈希有关?!直接寄。Statement这个系统首先需要输入一棵\(n\)个点的有根树和一个长度为\(m\)的序列\(a\),接下来需要实现\(q\)个操作。操作分两种:1xlr表示设定起点为有根树的节点\(x\),接下来......