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, ... 
随机推荐
- centos6.5 单点kafka测试
			一,kafka解压到/usr/local/下后,修改配置文件 vim config/zookeeper.properties 修改如下几行: dataDir=/usr/local/zookeeper/ ... 
- python-爬虫-scrapy
			入门: 下载:pip install scrapy 工程:scrapy startproject 工程名 Spider: scrapy genspider 爬虫名 url (--nolog//可选不 ... 
- Web后台管理系统
			开发语言:C# 数据库:sql2008 登录页面 后台管理首页 部分操作页面 后台管理系统,界面简洁,大方,操作简单,所有功能可定制开发. 后台管理系统制作 如果您有需要后台管理系统制作,请扫描添加微 ... 
- Linux详细介绍以及常用命令
			Linux系统说明 Linux( 诞生于1991.10.5) 继承了Unix以网络为核心的设计思想, 是一个性能稳定的多用户网络操作系统. Linux这个词严格意义上只表示Linux内核, 但日常中, ... 
- jQuery  虚拟数字键盘代码
			先上效果: js直接应用: $('input').mynumkb(); 就出来效果 HTML: <input maxlength="4" type="tex ... 
- JS字符串格式化~欢迎来搂~~
			/* 函数:格式化字符串 参数:str:字符串模板: data:数据 调用方式:formatString("api/values/{id}/{name}",{id:101,name ... 
- 多线程基础知识---join方法
			join方法的作用 thread.join()方法用于把指定的线程加入到当前线程中,把当前线程的CPU执行时间让给另一个线程.比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继 ... 
- 项目使用Hbase进行数据快速查询的代码案例
			之前项目中对于数据详情的查询使用的ddb技术,由于成本过高,现考虑使用开源的hbase框架,借此机会进行hbase的代码案例记录,之前已经对 hbase的原理进行介绍,介绍了hbase中的rowkey ... 
- [转帖]为何 linux 要用 tar.gz,而不用 7z 或 zip?
			为何 linux 要用 tar.gz,而不用 7z 或 zip? http://embeddedlinux.org.cn/emb-linux/entry-level/201908/13-8776.ht ... 
- jenkins 控制台输出中文乱码
			jenkins在执行构建任务时会在 console output 进行任务的日志输出,但中文输出会乱码,如下图 解决办法: Manage Jenkins ---> 系统配置 ---> 全 ... 
