题目链接:http://codeforces.com/contest/522/problem/D

题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查询,输出在这个区间内的两个相等的数的最短距离,如果没有相等的则输出-1.

线段树+扫描线,线段树维护的值是区间的最小值,从后往前扫,然后每次要做的事有两个:

1.判断当前这个位置 i 的数刚刚是不是出现过,假设刚刚出现的位置是 l ,如果出现过,则在线段树中把l这个位置的值更新为 l - i,同时更新包含这个点的区间的最小值.

2.判断有没有以当前这个位置为左端点的查询区间,如果有,就在线段树中查找这个区间里面的最小值.

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<list>
using namespace std;
const int maxn = ,INF = 0x7fffff;
map<int,int> mp; int n,m,A[maxn];
struct node
{
int d,l,r;
}tree[*maxn];
struct Node
{
int flag,ans;
int l,r;
}Q[maxn];
bool cmp(Node a,Node b)
{
return a.l >= b.l;
}
void maketree(node *tree,int p)
{
if(tree[p].l == tree[p].r)
{
tree[p].d = INF;
return ;
}
int mid = (tree[p].l + tree[p].r) / ;
tree[*p].l = tree[p].l;
tree[*p].r = mid;
tree[*p+].l = mid + ;
tree[*p+].r = tree[p].r;
tree[*p].d = tree[*p+].d = INF;
maketree(tree,*p);
maketree(tree,*p+);
}
void update(node *tree,int p,int loc,int d)
{
if(tree[p].l == tree[p].r)
{
tree[p].d = min(tree[p].d,d);
return ;
}
int mid = (tree[p].l + tree[p].r) / ;
if(loc <= mid)
update(tree,*p,loc,d);
else update(tree,*p+,loc,d);
tree[p].d = min(tree[p].d,d);
}
int data_sear;
void search(node *tree,int p,int l,int r)
{
if(tree[p].l == l && tree[p].r == r)
{
data_sear = min(data_sear,tree[p].d);
return ;
}
int mid = (tree[p].l + tree[p].r) / ;
if(r <= mid) search(tree,*p,l,r);
else if(l <= mid && r > mid)
{
search(tree,*p,l,mid);
search(tree,*p+,mid+,r);
}
else if(l > mid) search(tree,*p+,l,r);
} bool cmp2(Node a,Node b)
{
return a.flag < b.flag;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i = ;i <= n;++i)
scanf("%d",&A[i]);
for(int i = ;i < m;++i)
{
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].flag = i;
Q[i].ans = INF;
}
sort(Q,Q+m,cmp); //按照左端点排好序,方便下面二分查找
tree[].l = ;
tree[].r = n;
tree[].d = INF;
maketree(tree,); //构建好线段树
mp.clear();
int f = ; //指向当前的查询
for(int i = n;i >= ;--i)
{
if(mp[A[i]] != )
update(tree,,mp[A[i]],mp[A[i]]-i); //更新线段树
mp[A[i]] = i;
while(f < m && Q[f].l == i)
{
data_sear = INF;
search(tree,,Q[f].l,Q[f].r); //查询这个区间内的最小值
Q[f].ans = (data_sear <= n? data_sear:-);
f++;
}
}
sort(Q,Q+m,cmp2);
for(int i = ;i < m;++i)
printf("%d\n",Q[i].ans);
}
return ;
}

Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)的更多相关文章

  1. Codeforces VK Cup 2015 - Qualification Round 1 D. Closest Equals 离线线段树 求区间相同数的最小距离

    D. Closest Equals Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/prob ...

  2. codeforces 522D. Closest Equals 线段树+离线

    题目链接 n个数m个询问, 每次询问输出给定区间中任意两个相同的数的最近距离. 先将询问读进来, 然后按r从小到大排序, 将n个数按顺序插入, 并用map统计之前是否出现过, 如果出现过, 就更新线段 ...

  3. $Codeforces\ 522D\ Closest\ Equals$ 线段树

    正解:线段树 解题报告: 传送门$QwQ$ 题目大意是说给定一个数列,然后有若干次询问,每次询问一个区间内相同数字之间距离最近是多少$QwQ$.如果不存在相同数字输出-1就成$QwQ$ 考虑先预处理出 ...

  4. D. Closest Equals(线段树)

    题目链接: D. Closest Equals time limit per test 3 seconds memory limit per test 256 megabytes input stan ...

  5. codeforces VK Cup 2015 - Qualification Round 1 B. Photo to Remember 水题

    B. Photo to Remember Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/522/ ...

  6. Codeforces VK Cup 2015 A.And Yet Another Bracket Sequence(后缀数组+平衡树+字符串)

    这题做得比较复杂..应该有更好的做法 题目大意: 有一个括号序列,可以对其进行两种操作: ·        向里面加一个括号,可以在开头,在结尾,在两个括号之间加. ·        对当前括号序列进 ...

  7. Codeforces Round VK Cup 2015 - Round 1 (unofficial online mirror, Div. 1 only)E. The Art of Dealing with ATM 暴力出奇迹!

    VK Cup 2015 - Round 1 (unofficial online mirror, Div. 1 only)E. The Art of Dealing with ATM Time Lim ...

  8. 51nod 1494 选举拉票 (线段树+扫描线)

    1494 选举拉票  题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 现在你要竞选一个县的县长.你去对每一个选民进 ...

  9. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

随机推荐

  1. AC日记——最大数 洛谷 P1198 [JSOI2008]

    题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制:L不超过当前数列的长度. 2. 插入操作 ...

  2. 原生js实现jquery库中选择器的功能(jquery库封装一)

    今天是2017.1.1,新的一天,新的一年,新的一年里继续夯实基础知识,在工作中多些项目,多思考,多总结,前端是不断更新,在更新的过程中也是发现乐趣和挑战自我的过程,希望年轻的我和年轻的javascr ...

  3. IdentityHashMap类:增加相同Key(键)内容的结果

    正常Map操作中,key是不能重复的. 先看使用HashMap()操作,增加相同Key内容的结果: 先看代码: package 类集; import java.util.HashMap; import ...

  4. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 适合大型企业信息化应用使用的角色权限管理体系

    每个人外表看看都没什么大区别.但是内在的知识.处理问题的能力.解决问题的能力.头脑灵活性都会有很大的差距.软件组件也是一样,有些组件编写厉害,想问题深入,能处理的难题也多,构思巧妙. 通用快速开发平台 ...

  5. Android SQLITE 操作工具类

    首先创建一个类 DatabaseHelper 继承SQLiteOpenHelper帮助类,定义数据库版本,数据库名称,创建表名. private static final int DATABASE_V ...

  6. 用C#实现封装

    用C#实现封装 1.属性对外公开类似于类的接口实现对字段的访问;2.字段为private只能在内部被直接访问,如果当属性为只读,那么可以将形参直接对字段赋值.(有没有更好的方法?);3.可以通过关键字 ...

  7. Eclipse+maven创建webapp项目<二>(转)

    原文地址:http://www.cnblogs.com/candle806/p/3439469.html 1.开启eclipse,右键new-->other,如下图找到maven project ...

  8. 使用 antd Table组件, 异步获取数据

    使用React.js + Redux + antd 制作CMS 后台内容管理系统,分享一点点积累,欢迎讨论. 在this.state中初始化数据: this.state = { pageNum:1, ...

  9. less简介

    Less是一种动态的样式语言.Less扩展了CSS的动态行为,比如说,设置变量(Variables).混合书写模式(mixins).操作(operations)和功能(functions)等等,最棒的 ...

  10. AOJ DSL_2_A Range Minimum Query (RMQ)

    Range Minimum Query (RMQ) Write a program which manipulates a sequence A = {a0,a1,...,an−1} with the ...