首页 > 其他分享 >CF2009G2 Yunli's Subarray Queries (hard version)

CF2009G2 Yunli's Subarray Queries (hard version)

时间:2024-11-10 16:46:40浏览次数:1  
标签:CF2009G2 窗口 version int rep hard st tag mp

首先考虑计算 \(f([a_1, a_2,\cdots,a_k])\):发现对于在同一条斜线上的 \(a_i\), \(a_i-i\) 的值是相同的。统计出 \(a_i-i\) 的众数 \(x\),则 \(k-x\) 次操作就可以将这一段变成连续数组。

处理好了第一个长度为 \(k\) 的段,向右滑动窗口,只需要把左侧出去的 \(a_1-1\) 出现次数减 1,右侧进来的 \(a_{k+1}-(k+1)\) 出现次数加 1,就可以动态维护上文的众数 \(x\) 了。具体实现上,我们可以用一个 map 维护窗口中 \(a_i-i\) 各种取值的出现次数,把这些出现次数扔进 multiset,最大值 *s.rbegin() 就是 \(a_i-i\) 的众数。到这里,我们用 \(O(n\log n)\) 的复杂度求出每个长度为 \(k\) 的窗口的最小操作数,easy version 就做完了。

hard version 式子的意思可以理解为:对于给定的询问 \(l,r\),要在区间的每个长度大于 \(k\) 的前缀上——第一个前缀长度为 \(k\),包含了一个完整窗口;第二个长度为 \(k+1\),包含了两个窗口,依此类推——对每个窗口的最小操作数求一次 \(\min\)。

为此,我们先把询问离线下来,按区间左端点排序,然后从后往前遍历每个长度为 \(k\) 的窗口,扔进一个单调栈里。如果当前窗口 \(i\) 的操作数 \(x\) 比栈顶的窗口大,则放在栈顶,并在线段树上的位置 \(i\) 单点加 \(x\);如果操作数小,就弹栈,直到栈顶窗口 \(top\) 的操作数 \(x_{top} < x\),然后在线段树上从 \(i\) 到 \(top-1\) 区间赋值 \(x\) (具体实现上两种情况可以合并,一个都弹不了则区间为 \([i,i]\))。随后,检查是否有询问的左端点 \(l=i\),把这些询问一一处理(线段树区间 \(\min\))。这一部分的复杂度 \(O(n\log n+q)\),这道题就完成了。

#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = a; i <= b; i++)
#define dep(i, a, b) for (int i = a; i >= b; i--)
#define endl '\n'

using ll = long long;
using ull = unsigned long long;
using vi = vector<int>;
using vll = vector<ll>;

struct seg {
    vi L, R, tag;
    vll sum;

#define ls p << 1
#define rs p << 1 | 1
#define mid ((L[p] + R[p]) >> 1)

    seg(int n)
        : L(n * 4 + 10), R(n * 4 + 10), sum(n * 4 + 10), tag(n * 4 + 10) {
        bld(1, 1, n);
    }

    void up(int p) { sum[p] = sum[ls] + sum[rs]; }

    void bld(int p, int l, int r) {
        L[p] = l, R[p] = r, tag[p] = -1;
        if (l == r) return;
        bld(ls, l, mid);
        bld(rs, mid + 1, r);
        up(p);
    }

    void atg(int p, ll v) { tag[p] = v, sum[p] = v * (R[p] - L[p] + 1); }

    void pd(int p) {
        if (tag[p] == -1) return;
        atg(ls, tag[p]), atg(rs, tag[p]);
        tag[p] = -1;
    }

    void upd(int p, int l, int r, int v) {
        if (l <= L[p] && R[p] <= r) return atg(p, v), void();
        pd(p);
        if (l <= mid) upd(ls, l, r, v);
        if (r > mid) upd(rs, l, r, v);
        up(p);
    }

    ll ask(int p, int l, int r) {
        if (l <= L[p] && R[p] <= r) return sum[p];
        pd(p);
        ll res = 0;
        if (l <= mid) res += ask(ls, l, r);
        if (r > mid) res += ask(rs, l, r);
        return res;
    }

#undef ls
#undef rs
#undef mid
};

struct qry {
    int l, r, id;
    bool operator<(const qry& o) const {
        return l < o.l;
    }
};

void solve() {
    int n, k, m;
    cin >> n >> k >> m;
    vi a(n + 1);
    rep(i, 1, n) cin >> a[i];
    map<int, int> mp;
    multiset<int> s;
    rep(i, 1, n) s.insert(0);
    rep(i, 1, k - 1) {
        s.erase(s.find(mp[a[i] - i]));
        mp[a[i] - i]++;
        s.insert(mp[a[i] - i]);
    }
    int K = n - k + 1;
    vi c(K + 1);
    rep(i, k, n) {
        s.erase(s.find(mp[a[i] - i]));
        mp[a[i] - i]++;
        s.insert(mp[a[i] - i]);
        int p = i - k + 1;
        c[p] = k - *s.rbegin();
        s.erase(s.find(mp[a[p] - p]));
        mp[a[p] - p]--;
        s.insert(mp[a[p] - p]);
    }
    vector<qry> q(m + 1);
    rep(i, 1, m) {
        q[i].id = i;
        cin >> q[i].l >> q[i].r;
    }
    sort(q.begin() + 1, q.end());
    seg tr(K);      // i维护前缀l~i最小步数
    stack<int> st;  // 单调栈
    vll ans(m + 1);
    int j = m;
    dep(i, K, 1) {
        while (!st.empty() && c[st.top()] >= c[i]) st.pop();
        int end = st.empty() ? K : st.top() - 1;
        st.push(i);
        tr.upd(1, i, end, c[i]);
        for (; j && q[j].l == i; j--)
            ans[q[j].id] = tr.ask(1, q[j].l, q[j].r - k + 1);
    }
    rep(i, 1, m) cout << ans[i] << endl;
}

int32_t main(int t = 1) {
    cin >> t;
    while (t--) solve();
}

标签:CF2009G2,窗口,version,int,rep,hard,st,tag,mp
From: https://www.cnblogs.com/th19/p/18538191

相关文章

  • ffmpeg Video and Audio file format conversion
    Anysupportedfileformatandprotocolcanserveasinputtoffmpeg:Examples:YoucanuseYUVfilesasinput:ffmpeg-i/tmp/test%d.Y/tmp/out.mpgItwillusethefiles:/tmp/test0.Y,/tmp/test0.U,/tmp/test0.V,/tmp/test1.Y,/tmp/test1.U,/tmp/test1.V,etc......
  • ShardingJDBC:轻松应对海量数据挑战
    前言在当今大数据时代,海量数据的存储和访问成为了系统设计的瓶颈。单一数据库实例往往难以承受如此巨大的负载,从而导致性能下降甚至服务崩溃。为了解决这个问题,分库分表成为了一种常见的解决方案。它将数据分散存储到多个数据库实例或表中,从而有效地提升了系统的容量和性能......
  • 硬件加速(Hardware Acceleration)指的是使用专门的硬件组件来加速某些计算任务的处理速
    硬件加速:GPU、FPGA与其他加速技术硬件加速(HardwareAcceleration)指的是使用专门的硬件组件来加速某些计算任务的处理速度,而不是依赖传统的中央处理器(CPU)。随着技术的不断发展,硬件加速已经成为许多高性能计算、人工智能(AI)、数据处理等领域的核心组成部分。常见的硬件加速器包括图......
  • [极客大挑战 2019]HardSQL 1
    [极客大挑战2019]HardSQL1打开实例,发现是个登陆页面,查看源代码,发现又是GET提交check.php万能密码尝试不太行,怀疑字段或者空格被过滤,尝试闭合不加其他东西确认空格、union、and等都被过滤了,尝试加个括号并未出现你可知被我速住了,臭弟弟字样,()未被过滤吧,尝试采用upda......
  • Richard Matthew Stallman
      RichardMatthewStallman被誉为自由软件的斗士和精神领袖,是伟大的理想主义者。作品:GNUEmacsGPLCopyLeftFSF  进入八十年代后,黑客社群在软件工业商业化的强大压力下日渐土崩瓦解,黑客文化正在受到攻击,Matthew作为一名黑客,于1985年发表了著名的GNU宣言(GNUManifes......
  • yarn安装报错 Unrecognized option: --version Error: Could not create the Java Vir
    在自己电脑上安装yarn报错,Unrecognizedoption:--versionError:CouldnotcreatetheJavaVirtualMachine.Error:Afatalexceptionhasoccurred.Programwillexit.估计是和之前安装的hadoop冲突了使用whereyarn命令,找到安装yarn的目录C:\ProgramFiles\nodejs把......
  • springboot集成shardingjdbc
    1、引入POM<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency>2、修改yml配置spring:sharding......
  • D1 - The Endspeaker (Easy Version)
    题意:给出长为n的数组a,长为m的数组b和数字k,k初始值为1。每次可以执行以下两种操作之一:1.当k<=m时,k++;2.删除a前缀和小于等于b[k]的部分,同时cost+=m-k;求删完a的最小cost;如果不能删完a,输出-1.解:首先a最大值大于b[1]时无解。一开始想的是贪心,对于每一段a[i...j],如果其max(a[j...n......
  • sgx模拟执行,不需要sgx硬件---sgx executed in simulation,No need to support hardwar
    sgxexecutedinsimulation使用项目:https://github.com/intel/linux-sgx.git前言:目前国内和国外互联网上关于使用模拟模式来完成sgx的博客我是真的一点没有找到,因此自己写一份博客来完成记录环境:Ubuntu22.04不支持sgx,没有硬件存在(mac也可以按照本教程来完成工作)......
  • linux 内核 LINUX_VERSION_CODE 和 KERNEL_VERSION 宏定义 版本信息
    由于Linux版本的在不断更新,当设备驱动去兼容不同版本的内核时,需要知道当前使用的内核源码版本,以此来调用对应版本的内核API,这两个宏定义在文件/usr/include/linux/version.h#defineLINUX_VERSION_CODE263213#defineKERNEL_VERSION(a,b,c)(((a)<<16)+((b)<<8)+(c))我安......