首页 > 其他分享 >「KTSC 2024 R2」跳跃游戏 题解

「KTSC 2024 R2」跳跃游戏 题解

时间:2024-10-29 22:10:02浏览次数:5  
标签:KTSC cur R2 int 题解 LL pos len mx

睡了一觉,打呼噜被老胡叫醒了/lh 睡醒场切,vector find 是 \(O(size)\) 的调了 40 min/fn

思路

考虑最终得到了 \(\mathcal O(Q)\) 个连续的 \((len, val)\) 代表 线段长度 和 线段的 \(A_i\),可以用 map 简单得到。

结论:必然存在一种方案,使得在 \((i - K, i]\) 中必然存在跳跃的起点或终点。证明:否则 \(i - K\) 必然没有,可以从 \(i - K\) 跳到 \(i\),必然不劣。

若 \(len\ge K\),令 \(len = pK + q\), 则必然有跳了至少 \(p\) 次,故直接累加并让 \(len = q\),此时得到的 \(len\in (0, K)\),想到从左往右扫,并维护 \(ans_i\) 为在 \(i\) 处的最大值,可以想到当前为 \(i\) 时只记录 \((i - K, i]\) 的 \(ans\)。

考虑有一个 \((len,val)\) 加入,相当于 \(cur = cur + len\),\(cur\) 代表的是当前 \([0, cur]\) 是比较大的,而 \((cur, K)\) 是比较小的,那么是 \((cur, cur + len]\) 区间加,和 \((cur, cur + len]\) 区间对 \(f_{cur}\) 取 \(\max\),可以用基础的线段树维护,离散化一下常数可能会小一点。

代码

#include<bits/stdc++.h>
#define rep(i,l,r) for (int i(l), i##end(r); i <= i##end; ++i)
#define per(i,r,l) for (int i(r), i##end(l); i >= i##end; --i)
#define LL long long
#define fi first
#define se second
#define eb emplace_back
#define PII pair <int, int>
using namespace std;

const int N = 5e5 + 9;
LL n, K; int q;
vector <pair <LL, int> > seg;
map <LL, int> mp;
void cmax(LL &a, LL b) {if (a < b) a = b;}

LL ans0, ans1;
const LL inf = 1e18;
vector <LL> pos;
struct SegmentTree {
    #define lc (p << 1)
    #define rc (p << 1 | 1)
    LL mx[N << 2], tag1[N << 2], tag2[N << 2];
    void addtag1(int p, LL v) {
        mx[p] += v;
        tag1[p] += v;
        tag2[p] += v;
    }
    void addtag2(int p, LL v) {
        cmax(mx[p], v);
        cmax(tag2[p], v);
    }
    void pushdown(int p) {
        if (tag1[p]) {
            addtag1(lc, tag1[p]);
            addtag1(rc, tag1[p]);
            tag1[p] = 0;
        }
        if (tag2[p]) {
            addtag2(lc, tag2[p]);
            addtag2(rc, tag2[p]);
            tag2[p] = 0;
        }
    }
    void add(int ql, int qr, LL v, int p = 1, int l = 0, int r = pos.size() - 1) {
        if (ql <= l && r <= qr) {
            addtag1(p, v);
            return ;
        }
        if (qr < l || r < ql) return ;
        pushdown(p);
        int mid = (l + r) >> 1;
        add(ql, qr, v, lc, l, mid);
        add(ql, qr, v, rc, mid + 1, r);
        mx[p] = max(mx[lc], mx[rc]);
    }
    void mdf(int ql, int qr, LL v, int p = 1, int l = 0, int r = pos.size() - 1) {
        if (ql <= l && r <= qr) {
            addtag2(p, v);
            return ;
        }
        if (qr < l || r < ql) return ;
        pushdown(p);
        int mid = (l + r) >> 1;
        mdf(ql, qr, v, lc, l, mid);
        mdf(ql, qr, v, rc, mid + 1, r);
        mx[p] = max(mx[lc], mx[rc]);
    }
    LL query(int loc, int p = 1, int l = 0, int r = pos.size() - 1) {
        if (l == r) return mx[p];
        pushdown(p);
        int mid = (l + r) >> 1;
        if (loc <= mid) return query(loc, lc, l, mid);
        return query(loc, rc, mid + 1, r);
    }
} tr;

void fAdd(LL l, LL r, int var) {
    if (r < K) {
        int L = lower_bound(pos.begin(), pos.end(), l) - pos.begin();
        int R = upper_bound(pos.begin(), pos.end(), r) - pos.begin() - 1;
        tr.add(L, R, var);
    }
    else {
        fAdd(l, K - 1, var);
        fAdd(0, r - K, var);
    }
}
void fMax(LL l, LL r, LL var) {
    if (r < K) {
        int L = lower_bound(pos.begin(), pos.end(), l) - pos.begin();
        int R = upper_bound(pos.begin(), pos.end(), r) - pos.begin() - 1;
        tr.mdf(L, R, var);
    }
    else {
        fMax(l, K - 1, var);
        fMax(0, r - K, var);
    }
}

long long play_game(long long N, int Q, long long K, vector<long long> L, vector<long long> R) {
    n = N; q = Q; ::K = K;
    rep (i, 0, q - 1) {
        LL l = L[i], r = R[i];
        ++mp[l];
        --mp[r + 1];
    }
    int sum = 0;
    for (auto p : mp) {
        if (next(mp.find(p.fi)) == mp.end()) break;
        LL l = p.fi, r = next(mp.find(p.fi))->fi - 1;
        sum += p.se;
        LL len = r - l + 1, val = sum;
        ans1 += len / K * val, len %= K;
        if (len == 0) continue;
        seg.eb(len, sum);
    }
    LL cur = 0; pos.eb(cur); 
    for (auto i : seg) {
        LL len = i.fi;
        cur = (cur + len) % K;
        pos.eb(cur);
    }
    sort(pos.begin(), pos.end()); pos.erase(unique(pos.begin(), pos.end()), pos.end());
    // build
    cur = 0;
    for (auto i : seg) {
        LL len = i.fi, val = i.se;
        fAdd(cur + 1, cur + len, val);
        fMax(cur + 1, cur + len, tr.query(lower_bound(pos.begin(), pos.end(), cur) - pos.begin()));
        cur = (cur + len) % K;
    }
    return ans1 + tr.mx[1];
}

标签:KTSC,cur,R2,int,题解,LL,pos,len,mx
From: https://www.cnblogs.com/SkyMaths/p/18514608

相关文章

  • ARC186A 官方题解-ChatGPT翻译
    基于图的重新表述对于一个元素为0或1的\(N\timesN\)矩阵\(A\),考虑从一个完整的二部图构建的有向图。该图的顶点由两部分组成:\((R_1,\dots,R_N)\)和\((C_1,\dots,C_N)\),其边的方向如下:如果\(A_{i,j}=1\),则边从\(R_i\)指向\(C_j\)如果\(A_{i,j}=0\),则边从\(C_i......
  • P9131 [USACO23FEB] Problem Setting P 题解
    P9131[USACO23FEB]ProblemSettingP题解注意到最终形成的困难序列是一个不断包含的子集的关系,包含是非严格单调的,考虑转化为单调的形式易于计数dp。具体地,对于一些相同的困难值\(i\),算出其内部排列数\(g(i)\),于是转化成了单调的dp形式。于是实际上计算\(dp_{i}\)表示......
  • [KTSC 2024 R1] 最大化平均值 题解
    先考虑封闭序列的个数,发现只有\(\mathcalO(n)\)个,可以建出小根笛卡尔树,以\((a_i,i)\)作为权值,于是相同的一定是\(i,rs_i,rs_{rs_i},\dots\)。考虑如果没有重复,询问相当于给出一棵树,每次询问\(subtree(u)\),保留一个含\(u\)的联通块的最大平均值。可以把每个节点用向......
  • NewStar2024-week4-Crypto
    Crypto圣石匕首sage直接运行脚本就有了importgmpy2beta=0.37delta=0.01n=round((1-2*beta-2*delta)/((1-beta)^2-2*delta-beta),6)e=3668637434348843171145584606519031375027610199908169273169275927238735031431533260375377791001464799116453803408104076615710166......
  • [题解][CSP-S2024]擂台游戏
    题意[CSP-S2024]擂台游戏(民间数据)题目描述小S想要举办一场擂台游戏,如果共有\(2^k\)名选手参加,那么游戏分为\(k\)轮进行:第一轮编号为\(1,2\)的选手进行一次对局,编号为\(3,4\)的选手进行一次对局,以此类推,编号为\(2^k-1,2^k\)的选手进行一次对局。第二轮在......
  • 跨域问题解决办法
            跨域问题在Web开发中是一个常见的问题,特别是在前后端分离的开发模式下。以下是一些解决跨域问题的办法:一、后端配置CORS(跨来源资源共享)CORS是一种机制,它使用额外的HTTP头来告诉浏览器一个网页的当前来源(域名、协议和端口)是否有权限访问另一个来源的资源。1......
  • 基于node.js+vue基于Android的罗宾逊R22零部件图纸检索系统(开题+程序+论文)计算机毕业
    本系统(程序+源码+数据库+调试部署+开发环境)带文档lw万字以上,文末可获取源码系统程序文件列表开题报告内容选题背景在航空领域,罗宾逊R22直升机是一款广泛应用的机型。关于飞机零部件图纸的管理与检索方面,现有研究多集中于大型客机或通用飞机整体的文档管理系统,专门针对罗宾......
  • 【OJ题解】C++ 把字符串转换成整数
    ......
  • 题解:P7306 [COCI2018-2019#1] Strah
    分享一个\(O(nm\logm)\)的方法。分析考虑每次在\(x\)轴上固定左端点,然后移动\(x\)轴上的右端点,并统计答案。考虑如何统计一个\(1\timesn\)的区域的贡献。显然长度为\(i\)的区间有\(n-i+1\)个,所以贡献即为:\[\begin{aligned}f(n)=&\sum^n_{i=1}i\left(n-i+1\ri......
  • 题解:P8245 [COCI2013-2014#3] PAROVI
    题意定义两个整数\(A,B\)之间的距离为这两个整数所有对应位上的数的差的绝对值之和,记为\(\operatorname{dist}(A,B)\)。特别地,如果\(A,B\)两数的位数不相同,则在位数较小的数前补足前导\(0\)。现在,给定两个整数\(L,R\),请你求出所有在区间\([L,R]\)内的整数对的距离和。......