首页 > 其他分享 >线段树

线段树

时间:2023-04-26 19:34:43浏览次数:25  
标签:ll return int 线段 mid add id

 1 #include<iostream>
 2 #include<string>
 3 #define ll long long
 4 const int N = 1e5 + 5;
 5 
 6 using namespace std;
 7 
 8 ll tree[N<<2]; // 线段树,可以是对应的结构体
 9 ll lz[N<<2]; // 延迟标记,也可以是结构体
10 
11 //lz标记下传
12 void push_down(int id, int l, int r) {
13     if (lz[id]) {
14         int mid = (l + r) / 2;
15         lz[id * 2] += lz[id];
16         lz[id * 2 + 1] += lz[id];
17         tree[id * 2] += 1LL * (mid - l + 1) * lz[id];
18         tree[id * 2 + 1] += 1LL * (r - mid) * lz[id];
19         lz[id] = 0;
20     }
21 }
22 
23 //左右树信息合并
24 void push_up(int id) {
25     tree[id] = tree[id * 2] + tree[id * 2 + 1];
26 }
27 // 创建线段树
28 void build(int id, int l, int r) {
29     if (l == r) {
30         cin >> tree[id];//初始化可根据自己的要求来改写;
31         return;
32     }
33     int mid = (l + r) / 2;
34     build(id * 2, l, mid);
35     build(id * 2 + 1, mid + 1, r);
36     push_up(id);
37 }
38 
39 // 区间更新,lr为更新范围,LR为线段树范围,add为更新值
40 
41 void update(int id, int L, int R, int l, int r, int add) {
42     if (l <= L && r >= R) {
43         lz[id] += 1LL * add;
44         tree[id] += 1LL * (R - L + 1) * add; // 更新方式
45         return;
46     }
47     push_down(id, L, R);
48     int mid = (L + R) / 2;
49     if (mid >= l) update(id * 2, L, mid, l, r, add);
50     if (mid < r) update(id * 2 + 1, mid + 1, R, l, r, add);
51     push_up(id);
52 }
53 // 区间查找
54 ll query(int id, int L, int R, int l, int r) {
55     if (l <= L && r >= R) return tree[id];
56     push_down(id, L, R);
57     int mid = (L + R) / 2;
58     ll sum = 0;
59     if (mid >= l) sum += query(id * 2, L, mid, l, r);
60     if (mid < r) sum += query(id * 2 + 1, mid + 1, R, l, r);
61     return sum;
62 }
63 
64 int main() {
65     int n, m;
66     cin >> n >> m;
67     build(1, 1, n);
68     while (m--) {
69         int ty;
70         cin >> ty;
71         if (ty == 1) {
72             int l, r,d;
73             cin >> l >> r >> d;
74             update(1, 1, n, l, r, d);
75         }
76         else {
77             int l, r;
78             cin >> l >>r;
79             cout << query(1, 1, n, l, r) << endl;
80         }
81     }
82     return 0;
83 }

 

标签:ll,return,int,线段,mid,add,id
From: https://www.cnblogs.com/xuanru/p/17357058.html

相关文章

  • HDU - 5649 线段树+区间二分答案 (好题)
    DZYhasasequencea[1…n].Itisapermutationofintegers1∼n.Nowhewantstoperformtwotypesofoperations:0lr:Sorta[l…r]inincreasingorder.1lr:Sorta[l…r]indecreasingorder.Afterdoingalltheoperations,hewilltellyouapositionk,andask......
  • [Week 18] 每日一题(C++,动态规划,线段树,数学)
    目录[Daimayuan]T1最长公共子序列(C++,DP,二分)输入格式输出格式数据范围输入样例输出样例解题思路[Daimayuan]T2喵喵序列(C++,序偶)题目描述输入格式输出格式样例输入样例输出样例说明数据范围双倍经验解题思路:[Daimayuan]T3漂亮数(C++,字符串)输入描述输出描述输入样例输出样例解题......
  • codeforces 573B B. Bear and Blocks(线段树+dp)
    题目链接:codeforces573B题目大意:给出n个连续塔,每个塔有高度hi,每次取走最外层的块,问需要多少次操作能够拿光所有的块。题目分析:首先我们可以知道第一次操作时,对于每个塔的变化满足如下的公式:hi=min(hi−1,hi−1,hi+1)每次操作都满足如下的递推式,我们递推一下得到第k次操作第i......
  • CF1797E 线段树 + 倍增 题解
    Preface有趣的一道ds,赛后不看题解做出来了。Solution首先有一个性质:\(\varphi(x)\)经过\(\mathcal{O}(\logx)\)次迭代后变为\(1\)。证明:若\(x\)为奇数,\(\varphi(x)=x\sum_{i=1}^{k}\frac{p_i-1}{p_i}\),\(p_i\)为奇数,所以\(p_i-1\)为偶数,我们就能得到\(\varphi(x)......
  • ARC159F Good Division【性质,DP,线段树】
    定义一个序列是好的当且仅当其可以通过每次删去一对相邻的不同的数把序列删空。给定一个长度为\(2n\)的序列\(a\),求有多少种划分方式使得每一段都是好的。答案对\(998244353\)取模。\(n\leq5\times10^5\),时限\(\text{5.0s}\)。先考虑什么样的数列是合法的,显然必要条......
  • Codeforces Round 850 (Div. 2, based on VK Cup 2022 - Final Round) E. Monsters (h
    传送门详细题解传送门  抄的ygg代码,向在这里说一下刚开始没看懂的部分。  求答案的时候是把所有的当前为止的所有数值加起来减去一个从1开始并且公差为1的等差数列的前size项和。其中size是当前最多能用到哪个位置,满足前size项能构成1,2,3,....,sz这样的形式。  假设我们......
  • xor (牛客多校) (线性基+ 线段树)
      思路:问xor起来有没有某个值,想到线性基然后发现问L-R区间的集合都要表示x,利用线性基的交集解决在利用线段树解决区间问题 #include<iostream>usingnamespacestd;typedefunsignedintui;constintmaxn=50005;structL_B{//线性基结构体ui......
  • 洛谷P5494 【模板】线段树分裂
    传送门  需要的前置知识:线段树合并。  感觉会了线段树合并这个就很简单,线段树分裂就是在把一颗权值线段树值域在[x,y]的区间分裂出来单独成一个线段树,那么我们只需要从新树q和旧树p的根节点一起走,如果走到当前p被[x,y]完全包含的路径就把p的编号给q,并且把p改为0就行了,注意......
  • P4069 [SDOI2016]游戏 李超线段树 维护区间优势线段的线段树
    传送门#include<iostream>#include<algorithm>#include<cstring>typedeflonglongll;typedefstd::pair<double,int>PDI;constintN=1e5,M=2e5+10;constllINF=123456789123456789;intn,m,cnt;inth[N],e[M],ne[M],......
  • 2022年江西省大学生程序设计竞赛 K.Peach Conference 线段树 懒标记清空
    传送门大致题意:  给定一个n和m,表示有区间大小为n,进行m次操作。  输入m行,每行3个数字v,l,r。如果v等于0则表示查询[l,r]内桃子的数量,如果v不为0则表示给[l,r]区间修改全部加v,如果有某个点数量+v小于0,则修改为0即可。大致思路:  这个题和势能也还是有些关系的。如果要......