首页 > 其他分享 >11.CF522D Closest Equals 线段树+离线询问

11.CF522D Closest Equals 线段树+离线询问

时间:2022-10-28 10:31:29浏览次数:93  
标签:11 rt return Closest int 离线 read ans define


11.CF522D Closest Equals 线段树+离线询问


给定序列,查询区间内距离最近的两个相等元素。

离线查询,按右端点加入贡献计算答案即可

洛谷传送门:​​CF522D Closest Equals - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)​

CF传送门:​​D. Closest Equals (codeforces.com)​

题目分析

给定序列,查询区间内距离最近的两个相等元素。

此类涉及元素相等的问题,一般是维护每个元素上次出现的位置。

首先,我们可以对所有询问进行离线。然后按照右端点排序后开始加入贡献(与上次出现的距离)。然后固定右端点查询即可:

记录 表示在 中跟 相同最近的位置。考虑离线,把询问按右端点排序,如果 就把 的位置修改为 ,然后就是区间求最小值了,注意到数据范围很大,需要进行离散化。

怎么会是黑题?假的吧。

Code

#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;

const int N = 5e5 + 10, MOD = 1e9 + 7;
int a[N], b[N];

namespace ffastIO {
const int bufl = 1 << 15;
char buf[bufl], *s = buf, *t = buf;
inline int fetch() {
if (s == t) { t = (s = buf) + fread(buf, 1, bufl, stdin); if (s == t) return EOF; }
return *s++;
}
inline int read() {
int a = 0, b = 1, c = fetch();
while (!isdigit(c))b ^= c == '-', c = fetch();
while (isdigit(c)) a = a * 10 + c - 48, c = fetch();
return b ? a : -a;
}
}

namespace SegTree{
#define ls lc[rt]
#define rs rc[rt]
#define lson ls, l,
#define rson rs, mid + 1,

int lc[N << 2], rc[N << 2], tree[N << 2], tot;

void build(){ memset(tree, 0x3f, sizeof(tree)); }

void update(int &rt, int l, int r, int pos, int val){
if(!rt) rt = ++tot;
if(l == r) return (void)(tree[rt] = val);
int mid = l + r >> 1;
if(mid >= pos) update(lson, pos, val);
else update(rson, pos, val);
tree[rt] = min(tree[ls], tree[rs]);
}

int query(int rt, int l, int r, int L, int R){
if(l >= L && r <= R) return tree[rt];
int mid = l + r >> 1, ans = 1e16;
if(mid >= L) ans = min(ans, query(lson, L, R));
if(mid < R) ans = min(ans, query(rson, L, R));
return ans;
}

}

struct info{ int id, l; };

vector<info> q[N];
int ans[N], pre[N], lst[N];

using ffastIO::read;
using SegTree::query;
using SegTree::update;

#define SEGRG root, 1,

inline void solve(){
SegTree::build();
int n = read(), m = read(), root = 0;
for(int i = 1; i <= n; i++) a[i] = b[i] = read();
sort(b + 1, b + 1 + n);
int n1 = unique(b + 1, b + 1 + n) - (b + 1);
auto get = [&](int x) { return lower_bound(b + 1, b + 1 + n1, x) - b; };
for(int i = 1; i <= n; i++){
a[i] = get(a[i]);
pre[i] = lst[a[i]], lst[a[i]] = i;
}
for(int i = 1; i <= m; i++){
int l = read(), r = read();
q[r].emplace_back(info{i, l});
}

for(int i = 1; i <= n; i++){
if(pre[i]) update(SEGRG, pre[i], i - pre[i]);
for(auto qu : q[i]) ans[qu.id] = query(SEGRG, qu.l, i);
}

for(int i = 1; i <= m; i++) cout << (ans[i] > 1000000 ? -1 : ans[i]) << endl;
}

signed main(){
solve();
return 0;
}


标签:11,rt,return,Closest,int,离线,read,ans,define
From: https://blog.51cto.com/u_12372287/5803565

相关文章

  • 11.AOP
    11.AOP11.1.什么是AOP(再不影响原有代码的情况下,实现动态增强)AOP(AspectOrientedProgramming),意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护......
  • WIN10-IE11 下的企业网银交易签名失败/不显示账户名/无法交易 解决方法
     一般的设置,我们可以通过该网银助手就可以解决。我们这里谈的是:在农行网银助手检测一切正常时,在公司账户转账付款时,总提示“签名失败!”的问题。我们知道最新版本下的IE启......
  • Win11下强制使用IE11的方法
    因个别原因很多需要IE访问的页面,在edge中纵使打开ie模式也无法正常浏览。此时,无需安装任何插件即可打开原版IE11:1.设置edge浏览器的ie模式为从不强制使用edge打开ie页面2.......
  • uva 11584
    给一个字符串,划分成最少的回文串如aaadbccb---->aadbccb f[i]=miin{f[j]+1}j<i, 且s[j...i]是回文串 #include<iostream>#include<cstring>using......
  • 泛化之美 —— C++11 可变参数模板的妙用
    概述首先这篇文章出自博客园作者:[......
  • uva 1169
    地图上有n个点(x,y),机器人从(0,0)出发到每个点捡垃圾(w[i]),承载最大重量为m在每个点都可以返回(0,0)点放置垃圾最短路程?n<1e5,m<100 看完范围只能设f[i],考虑前i......
  • NCC2111,eclipse配置
    -Dnc.exclude.modules=${FIELD_EX_MODULES}-Dnc.runMode=develop-Dnc.server.location=${FIELD_NC_HOME}-DEJBConfigDir=${FIELD_NC_HOME}/ejbXMLs-DExtServiceConfigD......
  • 力扣 116. 填充每个节点的下一个右侧节点指针 [无queue]
    116.填充每个节点的下一个右侧节点指针给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:structNode{intval;No......
  • uva11235
    给一个非降序的排列{a},多次询问区间(l,r)中出现次数最大的值,输出这个次数 比如12668881023 相同的数据靠在一起,我们将相同数据组成一块(要处理出这个块的信......
  • ACWing 3548 -- 离线算法
    题目描述双端队列思路参考代码......