水题笔记: codevs1081 线段树练习2 [重口味线段树(区间修改)]

来源:互联网 发布:听力灵敏度测试软件 编辑:程序博客网 时间:2024/05/01 15:12

扯一扯

昨天(其实好像还有前天?)水了五道搜索…(已经成为了一只咸宽嫂…)
然后…就啥都不会了QAQ我好菜啊QAQ

懵逼的 题目

http://codevs.cn/problem/1081/
(话说那些水过去的smg???就我一个辣鸡老老实实用了线段树???人与人之间基本的信任嘞???)

扯淡的 题解

emm…上一篇文(kou)章(hu)讲了重口味的建树/区间查询/单点修改…这篇就讲讲区间修改咯QAQ
emm…好像网上讲重口味区间修改的很少啊….
重口味区间修改的巧妙在于不下传标记,而是在”回溯”的时候根据标记来修改返回值,了解了这个就好办辣QAQ修改和普通线段树一样,打标记,查询的时候再根据标记调整
修改的时候与区间查询操作极为相似…因为都是要求”不漏 不重”嘛

沙茶的 代码

// codevs 1081.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#define MAXN (100000 + 5)using namespace std;struct xds{    int zh;    int lz;}a[8 * MAXN];int n;void js();void xg(int, int, int);int cx(int);int main(){    int srn;    cin >> srn;    n = 1;    while (n < srn) n <<= 1;    for (int i = 1; i <= srn; i++)    {        cin >> a[n + i].zh;        a[srn + i].lz = 0;    }    js();    /*for (int i = 1; i <= n + srn + 1; i++)    {        cout << a[i].zh << " ";    }    puts("");*/    int m;    cin >> m;    for (int i = 1; i <= m; i++)    {        int e, srx, sry, srz;        cin >> e;        if (e == 1)        {            cin >> srx >> sry >> srz;            xg(srx, sry, srz);        }        else        {            cin >> srx;            cout << cx(srx) << endl;        }    }    return 0;}void js(){    for (int i = n - 1; i >= 1; i--)    {        a[i].zh = a[i << 1].zh + a[(i << 1) | 1].zh;        a[i].lz = 0;    }}int cx(int x){    x += n;    int re = a[x].zh;    while (x)    {        re += a[x].lz;        x >>= 1;    }    return re;}void xg(int l, int r, int z){    for (int i = l + n - 1, j = r + n + 1; (i ^ j) != 1; i >>= 1, j >>= 1)    {        if (!(i & 1))               a[i ^ 1].lz += z;        if (j & 1)              a[j ^ 1].lz += z;    }}

By 好菜的 Cansult
又及: 明天好像要淘汰人啊我好方啊
这里写图片描述

原创粉丝点击