F - One Occurrence CodeForces - 1000F (线段树+离线处理)
You are given an array aa consisting of nn integers, and qq queries to it. ii-th query is denoted by two integers lili and riri. For each query, you have to find any integer that occurs exactly once in the subarray of aa from index lili to index riri (a subarray is a contiguous subsegment of an array). For example, if a=[1,1,2,3,2,4]a=[1,1,2,3,2,4], then for query (li=2,ri=6)(li=2,ri=6) the subarray we are interested in is [1,2,3,2,4][1,2,3,2,4], and possible answers are 11, 33 and 44; for query (li=1,ri=2)(li=1,ri=2) the subarray we are interested in is [1,1][1,1], and there is no such element that occurs exactly once.
Can you answer all of the queries?
Input
The first line contains one integer nn (1≤n≤5⋅1051≤n≤5⋅105).
The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤5⋅1051≤ai≤5⋅105).
The third line contains one integer qq (1≤q≤5⋅1051≤q≤5⋅105).
Then qq lines follow, ii-th line containing two integers lili and riri representing ii-th query (1≤li≤ri≤n1≤li≤ri≤n).
Output
Answer the queries as follows:
If there is no integer such that it occurs in the subarray from index lili to index ririexactly once, print 00. Otherwise print any such integer.
Example
Input
61 1 2 3 2 422 61 2
Output
40
题意:
给你一个含有n个数的数组和q个询问,每一个询问给你一个区间l和r,请你输出一个在数组l~r区间中只出现一次的数,如果没有就输出0.
思路:
首先把询问按照r进行升序排序,来离线解决此问题。
我们用线段树维护一个pair<int,int>
first 和second 分别代表 这个位置的数当前位置下标和他前一个出现这个数的下标。
然后去询问区间询问区间中first 的最小值,判断是否比其区间的l小,如果小于则说明区间这个数仅出现一次,它的上一次如果存在的话,是在l左边。
代码实现起来细节还是很多的,多看代码理解一下吧。
其他做法可以参考这个大佬的博客(3个做法):https://blog.csdn.net/lzc504603913/article/details/83310266
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2) { ans = ans * a % MOD; } a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int *p);
const int maxn = 500010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE code * * STARTS HERE ***/
struct node {
pii num;
int l, r;
} segment_tree[maxn << 2];
void build(int rt, int l, int r)
{
segment_tree[rt].l = l;
segment_tree[rt].r = r;
segment_tree[rt].num = mp(0, 0);
if (l == r) {
return ;
}
int mid = (l + r) >> 1;
build(rt << 1, l, mid);
build(rt << 1 | 1, mid + 1, r);
}
void pushup(int rt)
{
segment_tree[rt].num = min(segment_tree[rt << 1].num, segment_tree[rt << 1 | 1].num);
}
void update(int rt, int pos, int pre)
{
if (segment_tree[rt].l == segment_tree[rt].r && segment_tree[rt].l == pos) {
segment_tree[rt].num.fi = pre;
segment_tree[rt].num.se = pos;
} else {
int mid = segment_tree[rt].l + segment_tree[rt].r >> 1;
if (pos <= mid) {
update(rt << 1, pos, pre);
} else {
update(rt << 1 | 1, pos, pre);
}
pushup(rt);
}
}
pii ask(int rt, int l, int r)
{
if (segment_tree[rt].l >= l && segment_tree[rt].r <= r) {
return segment_tree[rt].num;
}
pii res;
res.fi = inf;
int mid = (segment_tree[rt].r + segment_tree[rt].l) >> 1;
if (l <= mid) {
res = min(res, ask(rt << 1, l, r));
}
if (r > mid) {
res = min(res, ask(rt << 1 | 1, l, r));
}
return res;
}
int a[maxn];
struct aaaaa {
int l;
int r;
int id;
} b[maxn];
bool cmp(aaaaa aa, aaaaa bb)
{
if (aa.r == bb.r) {
return aa.l < bb.l;
} else {
return aa.r < bb.r;
}
}
int last[maxn];
int ans[maxn];
int main()
{
//freopen("D:\\code\\text\\input.txt","r",stdin);
//freopen("D:\\code\\text\\output.txt","w",stdout);
int n;
gbtb;
cin >> n;
build(1, 1, n);
repd(i, 1, n) {
cin >> a[i];
}
int q;
cin >> q;
repd(i, 1, q) {
cin >> b[i].l >> b[i].r;
b[i].id = i;
}
sort(b + 1, b + 1 + q, cmp);
int cur = 1;
repd(i, 1, q) {
for (; cur <= b[i].r; cur++) {
if (last[a[cur]]) {
update(1, last[a[cur]], inf);
}
update(1, cur, last[a[cur]]);
last[a[cur]] = cur;
}
auto temp = ask(1, b[i].l, b[i].r);
if (temp.fi < b[i].l) {
ans[b[i].id] = a[temp.se];
}
}
repd(i, 1, q) {
printf("%d\n", ans[i] );
}
return 0;
}
inline void getInt(int *p)
{
char ch;
do {
ch = getchar();
} while (ch == ' ' || ch == '\n');
if (ch == '-') {
*p = -(getchar() - '0');
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 - ch + '0';
}
} else {
*p = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9') {
*p = *p * 10 + ch - '0';
}
}
}
F - One Occurrence CodeForces - 1000F (线段树+离线处理)的更多相关文章
- 线段树+离线 hdu5654 xiaoxin and his watermelon candy
传送门:点击打开链接 题意:一个三元组假设满足j=i+1,k=j+1,ai<=aj<=ak,那么就好的.如今告诉你序列.然后Q次询问.每次询问一个区间[l,r],问区间里有多少个三元组满足 ...
- Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论
Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...
- 牛客练习赛53 E-老瞎眼pk小鲜肉(思维+线段树+离线)
前言 听说是线段树离线查询?? 做题做着做着慢慢对离线操作有点感觉了,不过也还没参透,等再做些题目再来讨论离线.在线操作. 这题赛后看代码发现有人用的树状数组,$tql$.当然能用树状数组写的线段树也 ...
- Codeforces Round #271 (Div. 2) F. Ant colony (RMQ or 线段树)
题目链接:http://codeforces.com/contest/474/problem/F 题意简而言之就是问你区间l到r之间有多少个数能整除区间内除了这个数的其他的数,然后区间长度减去数的个数 ...
- Codeforces Round #271 (Div. 2) F题 Ant colony(线段树)
题目地址:http://codeforces.com/contest/474/problem/F 由题意可知,最后能够留下来的一定是区间最小gcd. 那就转化成了该区间内与区间最小gcd数相等的个数. ...
- Codeforces Round #463 F. Escape Through Leaf (李超线段树合并)
听说正解是啥 set启发式合并+维护凸包+二分 根本不会啊 , 只会 李超线段树合并 啦 ... 题意 给你一颗有 \(n\) 个点的树 , 每个节点有两个权值 \(a_i, b_i\) . 从 \( ...
- Codeforces Round #207 (Div. 1) A. Knight Tournament (线段树离线)
题目:http://codeforces.com/problemset/problem/356/A 题意:首先给你n,m,代表有n个人还有m次描述,下面m行,每行l,r,x,代表l到r这个区间都被x所 ...
- codeforces 522D. Closest Equals 线段树+离线
题目链接 n个数m个询问, 每次询问输出给定区间中任意两个相同的数的最近距离. 先将询问读进来, 然后按r从小到大排序, 将n个数按顺序插入, 并用map统计之前是否出现过, 如果出现过, 就更新线段 ...
- lca 欧拉序+rmq(st) 欧拉序+rmq(线段树) 离线dfs 倍增
https://www.luogu.org/problemnew/show/P3379 1.欧拉序+rmq(st) /* 在这里,对于一个数,选择最左边的 选择任意一个都可以,[left_index, ...
随机推荐
- uni-app 实现热更新
前端打包 app 即把写好的静态资源文件套壳打包成 app ,而热更新即下载并替换 app 内部的静态资源文件,实现 app 的版本升级. 在uni-app 中,我们是如何实现热更新的呢?下面来看代码 ...
- vue后端返回路由表来进行权限管理,加载指定路由结构,不包含则不加载
创建vue项目,配置环境变量,后续需要用到.这里只配置生产环境和开发环境. 项目根目录创建 .env.production 文件 NODE_ENV=production VUE_APP_URL=htt ...
- 深入理解JVM(二)JVM内存模型
一.前言 上文讲过了虚拟机的内存划分,即,我们将内存分为线程共享和线程私有. 线程共享的即java堆,和方法区.java堆大家可能都不会陌生:而方法区中包含了常量池,他也被称为永久代.通常方法区也会被 ...
- JavaScript校验身份证,包含省份、长度、出生年月日、校验位的检测、性别、年龄
一.代码如下 let vcity = {11: '北京', 12: '天津', 13: '河北', 14: '山西', 15: '内蒙古', 21: '辽宁', 22: '吉林', 23: '黑龙江 ...
- typescript实现类规则
备注: 单独的 index.d.ts对于代码实现没有约束性,将约束和实现写在一个页面里有约束性,或者使用如下: // clock.interface.ts export interface Clock ...
- getopts的使用 + 创建空目录
1.getopts的经典例子 isRollback= rollbackVer="" targetGroup="" actionType="" ...
- tinymce 中我输入的内容 清空问题
<tinymce v-model="formItem.hDtContent" ref="content" @accessory="handlea ...
- 【Python】【基础知识】【内置常量】
Python的内置常量有: False.True.None.NotImplemented.Ellipsis.__debug__ 由 site 模块添加的常量:quit.exit.copyright.c ...
- 【LOJ】#3095. 「SNOI2019」字符串
LOJ#3095. 「SNOI2019」字符串 如果两个串\(i,j\)比较\(i < j\),如果离\(a_{i}\)最近的不同的数是\(a_{k}\),如果\(j < k\)那么\(i ...
- 对Android应用签名
Android使用包名作为唯一标识,当在同一台手机安装两个包名相同的应用,后安装的应用就会覆盖前面的应用(签名相同的情况下). 签名有两个主要作用: 1.确定发布者身份.由于应用开发者可以通过使用相同 ...