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, ...
随机推荐
- axios中的qs介绍
首先qs是一个npm仓库所管理的包,可通过npm install qs命令进行安装. 地址: https://www.npmjs.com/package/qs qs.parse().qs.string ...
- JavaScript中函数文档注释
/** 方法说明 * @method 方法名 * @for 所属类名 * @param{参数类型}参数名 参数说明 * @return {返回值类型} 返回值说明 */
- keepalived脑裂问题
一.对脑裂的理解 在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体.动作协调的HA系统,就分裂成为2个独立的个体.由于相互失去了联系,都以为是对方出了故障.两个节点上的HA软件像 ...
- Openstack知识点总结
Openstack: 一.云计算+openstack概念: 1.云计算是一种按使用量付费的模式,这种模式提供可用的,便捷的,按需的访问,通过互联网进入可配置的计算资源共享池(资源包括网络,计算,存储, ...
- smoothscroll
smoothscroll是一款jQuery插件,可以平滑地滚动到指定的地方. 可以解决chrome锚点失效的问题. 官方网站 http://iamdustan.com/smoothscroll/ gi ...
- kubernetes的namespaces总是Terminating
0.尝试强制删除不行 删除时带上–force --grace-period=0参数 ,无法删除:kubectl delete namespace rook-ceph --force --grace-p ...
- 线程的同步控制synchronized和lock的对比和区别
转载. https://blog.csdn.net/wu1226419614/article/details/73740899 我们在面试的时候,时常被问到如何保证线程同步已经对共享资源的多线程编程 ...
- Python—格式化输出
Python提供了很多种格式化方式(包括但不限于以下几种): [,]分隔 name = 'jack' age = -0.5 print(name, 'is', age, 'years old.') j ...
- sort()方法的用法,参数以及排序原理
sort() 方法用于对数组的元素进行排序,并返回数组.默认排序顺序是根据字符串Unicode码点.语法:arrayObject.sort(sortby):参数sortby可选.规定排序顺序.必须是函 ...
- Python(七) —— mock接口开发
mock接口开发 接口开发有很多框架,诸如 Django,flask,相比较而言,flask 是轻量级web开发框架,用来开发 mock 接口的不二之选.那你可能会问,什么叫 mock 接口呢?moc ...