题目链接: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. CodeForces 485C Bits[贪心 二进制]

    C. Bits time limit per test1 second memory limit per test256 megabytes inputstandard input outputsta ...

  2. idea快捷键(自用)

    idea快捷键(自用) 1.比如输入eclipse下面的main,sysout等,在idea里面同样可以实现,如下: sysout(sout 按tab),main(psvm按tab),具体可按照ctr ...

  3. [No000072]Windows环境变量列表

    环境变量是目录的可以直接在绝对路径中引用,所有值均可在CMD下用 echo 命令显示以查看. 最常用的有—— %APPDATA% %HOMEPATH% %ProgramFiles% %SYSTEMRO ...

  4. 大牛的博客 osharp以及EF的分析

    http://www.cnblogs.com/guomingfeng/ http://developer.51cto.com/art/201309/409950_all.htm

  5. LAMP.md

    LAMP Linux+Apache+Mysql/MariaDB+Perl/PHP/Python一组常用来搭建动态网站或者服务器的开源软件,本身都是各自独立的程序,但是因为常被放在一起使用,拥有了越来越 ...

  6. .NET定时任务执行管理器开源组件–FluentScheduler

    在日常项目里通常会遇到定时执行任务的需求,也就是定时器..NET Framework里关于定时器的类有3个,分别是System.Windows.Forms.Timer.System.Timers.Ti ...

  7. 网页游戏外挂辅助AMF模拟通讯必备

    class AMF_Post_Data { public List<byte> message; /// <summary> /// 初始化Message /// </s ...

  8. 教你一招:解决windows xp系统开机出现“disk checking has been canceled”

    问题重现: 问题分析: 系统的注册表被修改了. 问题解决: 1.(临时解决)开机时,按ESC或ENTER键取消. 2.(彻底解决)修改注册表文件. Win + R 打开运行 Regedit ,进入注册 ...

  9. bzoj4591 【Shoi2015】超能粒子炮·改

    由Lucas定理C(n,k)=C(n/2333,k/2333)*C(n%2333,k%2333)%2333 则ans=ΣC(n,i),(i<=k)  =C(n/2333,0)*C(n%2333, ...

  10. BZOJ3631: [JLOI2014]松鼠的新家

    传送门 树上的差分优化,很简单的一道题,应该属于NOIP2015TGD2T3的子问题. //BZOJ 3631 //by Cydiater //2016.10.25 #include <iost ...