ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

D-温暖的签到题

2019-05-12 10:40:37  阅读:268  来源: 互联网

标签:Lazy 签到 LL 温暖 Seg int MAXN root


链接:https://ac.nowcoder.com/acm/contest/892/D

题意:

给你一个长度为n的序列,初始为1,2,3...n,对其进行m次操作。 操作有两种: 1 l r  表示将区间[l,r]用 [1,2...r-l+1] 覆盖 2 l r 查询[l,r]的区间和

思路:

线段树

比赛时思路对的,但是代码写的太乱,没改出来,赛后重写。

Lazy我开二维数组,记录子节点左右对应的范围。

其他的就根普通线段树一样。

代码:

#include <bits/stdc++.h>
using namespace std;
 
typedef long long LL;
const int MAXN = 1e5+10;
 
LL Seg[MAXN*4];
LL Lazy[MAXN*4][2];
int n, m;
 
void PushUp(int root)
{
    Seg[root] = Seg[root<<1]+Seg[root<<1|1];
}
 
void PushDown(int root)
{
    if (Lazy[root][1] != 0)
    {
        LL lenl = Lazy[root][0];
        LL lenr = Lazy[root][1];
        LL lenmid = (lenl+lenr)/2;
        Seg[root<<1] = (lenl+lenmid)*(lenmid-lenl+1)/2;
        Seg[root<<1|1] = (lenmid+1+lenr)*(lenr-lenmid)/2;
        Lazy[root<<1][0] = lenl;
        Lazy[root<<1][1] = lenmid;
        Lazy[root<<1|1][0] = lenmid+1;
        Lazy[root<<1|1][1] = lenr;
        Lazy[root][0] = Lazy[root][1] = 0;
    }
}
 
void Build(int root, int l, int r)
{
    if (l == r)
    {
        Seg[root] = l;
        return;
    }
    int mid = (l+r)/2;
    Build(root<<1, l, mid);
    Build(root<<1|1, mid+1, r);
    PushUp(root);
}
 
void Update(int root, int l, int r, int ql, int qr)
{
    if (r < ql || qr < l)
        return;
    if (ql <= l && r <= qr)
    {
        LL lenl = l-ql+1, lenr = r-ql+1;
        Seg[root] = (lenl+lenr)*(r-l+1)/2;
        Lazy[root][0] = lenl;
        Lazy[root][1] = lenr;
        return;
    }
    PushDown(root);
    int mid = (l+r)/2;
    Update(root<<1, l, mid, ql, qr);
    Update(root<<1|1, mid+1, r, ql, qr);
    PushUp(root);
}
 
LL Query(int root, int l, int r, int ql, int qr)
{
    if (r < ql || qr < l)
        return 0LL;
    if (ql <= l && r <= qr)
        return Seg[root];
    PushDown(root);
    LL res = 0;
    int mid = (l+r)/2;
    res += Query(root<<1, l, mid, ql, qr);
    res += Query(root<<1|1, mid+1, r, ql, qr);
    return res;
}
 
int main()
{
    int op, l, r;
    cin >> n >> m;
    Build(1, 1, n);
    while (m--)
    {
        cin >> op >> l >> r;
        if (op == 1)
            Update(1, 1, n, l, r);
        else
            cout << Query(1, 1, n, l, r) << endl;
    }
 
    return 0;
}

  

标签:Lazy,签到,LL,温暖,Seg,int,MAXN,root
来源: https://www.cnblogs.com/YDDDD/p/10851279.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有