Live2D

【西北大学集训队选拔赛】D温暖的签到题(自创数据结构)

题目链接

#include <bits/stdc++.h>
#define NUM
#define ll long long
using namespace std;
 
int n, m;
 
struct node {
    int l;
    int sta;//第一个值
    int r;//长度
 
    ll sum(int l, int r) {		// 区间求和
        if (l < this->l) l = this->l;
        if (r > this->r) r = this->r;
        return (((l - this->l) + sta + (r - this->l) + sta)) * ((ll)r - l + 1) / 2;
    }
};
 
map<int, node> mp;	// 利用map自动排序,形成一个一维的块链,每一个块为一个给定规则的数据组成
 
ll cal(int l, int r) {		// 计算区间和,直接调用块内的自定义函数求和
    map<int, node>::iterator itl = mp.upper_bound(l);
    itl--;
    map<int, node>::iterator itr = mp.upper_bound(r);
    ll ans = 0;
    while (itl != itr) {
        ans += (*itl).second.sum(l, r);
        itl++;
    }
    return ans;
}
 
void update(int l, int r) {		// 更新块,删除被覆盖的块,形成新块
    if (r == 1)
        return;
    map<int, node>::iterator itl = mp.upper_bound(l);
    itl--;
    map<int, node>::iterator itr = mp.upper_bound(r);
    itr--;
    node templ = (*itl).second;
    node tempr = (*itr).second;
    tempr.sta = tempr.sta + (r + 1 - tempr.l) ;
    templ.r = l - 1;
    tempr.l = r + 1;
    itr++;
    while (itl != itr)
    {
        auto tmp = itl++;
        mp.erase(tmp);
    }
    node newnode;
    newnode.l = l;
    newnode.r = r;
    newnode.sta = 1;
    mp[l] = newnode;
    if (templ.l <= templ.r)
    {
        mp[templ.l] = templ;
    }
    if (tempr.l <= tempr.r)
    {
        mp[tempr.l] = tempr;
    }
}
 
int main()
{
    scanf("%d%d", &n, &m);
    int opt, l, r;
    node tot;
    tot.l = 1;
    tot.r = n;
    tot.sta = 1;
    mp[1] = tot;
    while (m--) {
        scanf("%d%d%d", &opt, &l, &r);
        if (opt == 1)
            update(l, r);
        else
            printf("%lld\n", cal(l, r));
    }
    return 0;
}
posted @ 2020-01-09 19:22  Shiroha  阅读(119)  评论(0编辑  收藏  举报