首页 > 其他分享 >Luogu P8518 [IOI2021] 分糖果

Luogu P8518 [IOI2021] 分糖果

时间:2023-11-01 14:36:35浏览次数:34  
标签:NODE int Luogu LL sgt vector MAX P8518 IOI2021

题目链接

 做这道题本意是为了补CCPC秦皇岛热身赛C,也就是2022 CCPC 华为云计算挑战赛 机器人那题

先考虑一个盒子怎么做,并且不考虑限制

那样的话可以得到时刻和盒子内球的数量的图像,考虑由这个不加限制的图像推出加上限制的实际答案

完整的图像一定是极大值极小值交错,考虑两个相邻的极大值和极小值,玩一下发现我们只关心它们之间差值是否大于限制 c-0
如果大于等于c了,那么时间上靠后出现的这个极大(小)值一定是触顶(底)的,最后求答案分类讨论一下就好

那么最后其实就是找最短的满足这个条件的后缀,发现这个不太好实现,其实上面描述的不够准确,我们关心的不是两个极值间怎么样,而是一段区间内的最大值和最小值之间距离是否大于等于c

对于最短的满足这个条件的后缀,左端点一定是这个后缀的最大值或最小值,根据左端点是最大值还是最小值分类讨论即可,这个可以二分解决
如果找不到满足条件的后缀,也就是整个区间都不满足,把负的值加回去就是结果

多个盒子的情况把操作离线就是一样的过程了

代码:

#include <bits/stdc++.h>
#define ls (x << 1)
#define rs (x << 1 | 1)
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int MAX_N = 2e5 + 10;
const LL MAX_V = 1e15, MIN_V = -1e15;

struct NODE{
    LL sum, maxv, minv, lzy;
    NODE(LL a = 0, LL b = 0, LL c = 0, LL d = 0) : sum{a}, maxv{b}, minv{c}, lzy{d} {}
};
struct SGT{
    NODE t[MAX_N << 2];
    void pushup(int x) {
        t[x].maxv = max(t[ls].maxv, t[rs].maxv);
        t[x].minv = min(t[ls].minv, t[rs].minv);
    }
    NODE Merge(NODE l, NODE r) {
        return NODE(0, max(l.maxv, r.maxv), min(l.minv, r.minv), 0);
    }
    void pushdown(int x) {
        LL v = t[x].lzy; t[x].lzy = 0;
        t[ls].lzy += v; t[ls].sum += v; t[ls].maxv += v; t[ls].minv += v;
        t[rs].lzy += v; t[rs].sum += v; t[rs].maxv += v; t[rs].minv += v;
    }
    void update(int L, int R, int l, int r, int x, int v) {
        if (L <= l && r <= R) {
            t[x].lzy += v; t[x].maxv += v; t[x].minv += v; t[x].sum += v;
            return;
        }
        pushdown(x);
        int mid = l + r >> 1;
        if (L <= mid) update(L, R, l, mid, ls, v);
        if (mid < R) update(L, R, mid + 1, r, rs, v);
        pushup(x);
    }
    LL getv(int D, int l, int r, int x) {
        if (l == r) return t[x].sum;
        pushdown(x);
        int mid = l + r >> 1;
        if (D <= mid) return getv(D, l, mid, ls);
        else return getv(D, mid + 1, r, rs);
    }
    LL query(int l, int r, int x, LL top, NODE suf) {
        if (l == r) {
            NODE cur = Merge(t[x], suf);
            if (cur.maxv - cur.minv <= top) return -cur.minv;
            if (cur.minv == t[x].minv)return top - cur.maxv;
            if (cur.maxv == t[x].maxv) return -cur.minv;
        }
        pushdown(x);
        int mid = l + r >> 1;
        NODE nxt = Merge(t[rs], suf);
        if (nxt.maxv - nxt.minv > top) return query(mid + 1, r, rs, top, suf);
        else return query(l, mid, ls, top, nxt);
    }
}sgt;
vector<PII> opt[MAX_N];
vector<int> distribute_candies(vector<int> c, vector<int> l, vector<int> r, vector<int> v) {
    int n = c.size(), q = l.size();
    for (int i = 0; i < q; ++i) {
        opt[l[i]].push_back({i + 1, v[i]});
        opt[r[i] + 1].push_back({i + 1, -v[i]});
    }
    vector<int> ret(n);
    for (int i = 0; i < n; ++i) {
        for (auto x : opt[i]) {
            sgt.update(x.first, q, 0, q, 1, x.second);
        }
        NODE suf = NODE(0, MIN_V, MAX_V, 0);
        ret[i] = int(sgt.query(0, q, 1, c[i], suf) + sgt.getv(q, 0, q, 1));
    }
    return ret;
}

  

标签:NODE,int,Luogu,LL,sgt,vector,MAX,P8518,IOI2021
From: https://www.cnblogs.com/xcysblog/p/17802079.html

相关文章

  • Luogu P4168 [Violet] 蒲公英 题解
    题目链接[Violet]蒲公英分析可以先将\(a[i]\)离散化然后考虑分块对于询问\(x,y\),\(x\)属于\(p\),\(y\)属于\(q\)当\(q-p<=1\)时直接暴力枚举即可,时间复杂度为\(O(\sqrt{n})\)\(else\)如图中间为分好块的地方我们发现,\(ans\)只可能为中间的众数或两边的......
  • USACO 图论题 - from Luogu
    题单记录:P2984[USACO10FEB]ChocolateGivingS这题直接按题意只有50pts,复杂度\(O(B~\cdotM\logN)\),显然超时,然后我就想啊想,发现从s->1->t跑两遍dij和1->s(t)跑一遍dij是等效的,没啥用......我居然还想了好久,才发现根本不需要每次都跑,跑一次预处理就行了..........
  • 真题 luogu.com.cn
           - ----------- ------ ------ ------ ------ ......
  • [刷题笔记] [算法学习笔记]树上差分 -- Luogu P3128
    DescriptionProblem:https://www.luogu.com.cn/problem/P3128FJ给他的牛棚的\(N\)个隔间之间安装了\(N-1\)根管道,隔间编号从\(1\)到\(N\)。所有隔间都被管道连通了。FJ有\(K\)条运输牛奶的路线,第\(i\)条路线从隔间\(s_i\)运输到隔间\(t_i\)。一条运输路线会给......
  • LuoguCF362B Petya and Staircases 题解
    分析简单排序题。首先Petya可以通过跨过一个台阶和两个台阶保证不经过脏台阶,但是不可以通过跨过三个台阶来保证不经过脏台阶,所以只要看有没有连续的三个脏台阶即可。同时,如果第一个台阶和最后一个台阶至少一个是脏台阶那么就不可以达成。AcceptedCode/*CodeByManipula*/......
  • Luogu P8594
    LuoguP8594Solution【形式化题意】你有\(1\timesx\)(\(x\)为任意正整数)的矩形各无穷多个和一个\(2\timesn\)的网格,请求出恰好选择其中\(k\)个矩形(可以选择相同的矩形)不重不漏地铺满整个网格的方案数。矩形可以旋转。\(n\leq2\times10^7,k\leq5000\)【解答】评价:......
  • [刷题笔记] Luogu P5658 [CSP-S 2019] 括号树
    Description给定一棵树,树的每个节点都有一个左括号或者右括号,求从根节点到每个点简单路径上的括号序列上合法的子括号序列数。Analysis显然树形dp。考虑如何设计状态,定义\(f_i\)表示从root到\(i\)节点的字串合法数量。考虑转移,如果当前的括号为左括号,我们无法和前面的......
  • 传纸条 luoguP1006
    题目描述小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排坐成一个mm行nn列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊......
  • Luogu CF1174C 题解
    这道题其实不难。\(\gcd(i,j)=1\),其实就是\(i\)与\(j\)互质。如果\(i\)与\(j\)不互质,那么我们一定要让\(a_i\)与\(a_j\)相同,只有这样,才能使\(a\)序列中的最大值最小化。所以,我们可以使用埃氏筛法,当筛到质数时,给它和它的倍数都赋值为一个新数。ACCode:#include......
  • Luogu P8651 题解
    这是让我最崩溃的一道橙题了。整整11次提交才AC。这道题有几个要点必须注意:判断日期是否合理。按顺序输出。判断重复的日期。首先,我们来看怎么判断日期是否合理。我们知道大月有\(31\)天,小月有\(30\)天,二月看平年闰年。所以,我们可以写出这样的代码:boolc......