zoukankan      html  css  js  c++  java
  • 宝石专家

    宝石专家

    题目描述

    Jim是一位宝石收藏品行家,在他的收藏室里保存着许多珍贵的宝石,磷叶石、钻石、摩根石、透绿柱石….,已知Jim有n个宝石,现在他将这n个宝石从1到n排开编号从1到n。Jim发现他所有的宝石中竟然有不少是完全相同的的,我们规定每个宝石都有一个特征值ai,当两个宝石特征值相等时及认为两个宝石相同。Jim发现两个相同的宝石离得越接近越明显。Jim现在有m个问题,他想问你在.编号l到r这一区间里的所有宝石中,两个相同宝石的最近距离是多少,(两个宝石的距离是它们编号的绝对值之差)。

    保证 l < r ,对于 ax和ay 若ax=ay 它们的距离为|x-y|。

    题意

    就是询问有许多线段,每一个线段有权值,询问在区间[l,r]中线段的最小权值。

    solution

    把每一个线段与询问离线并按左排序,用2-pointer从大向小扫,保证对于询问时所有的线段是合法的。

    然后使用线段树,询问 [0,r] 之间的最小值即可。

    #include<bits/stdc++.h>
    #define L first
    #define R second
    using namespace std;
    int n;
    int a[200100];
    struct sgt{
    	int val;
    	int l, r;
    }d[200100 << 2];
    pair <int,int> p[200100]; int pl;
    map <int,int> t;
    int ans[200100];
    int q;
    struct qry{
    	int id;
    	int l, r;
    	bool operator < (qry t){
    		return l < t.l;
    	}
    }st[200100];
    void build(int x,int l,int r){
    	d[x].l = l, d[x].r = r;
    	d[x].val = 0x3f3f3f3f;
    	if (l == r) return;
    	build(x<<1,l,(l+r)/2);
    	build(x<<1|1,(l+r)/2+1,r);
    }
    void insert(int x,int p,int val){
    	d[x].val = min(val, d[x].val);
    	if (d[x].l == d[x].r) return;
    	if (p <= d[x<<1].r) insert(x<<1,p,val);
    	else insert(x<<1|1,p,val);
    }
    int query(int x,int p){
    	if (d[x].l == d[x].r) return d[x].val;
    	if (p <= d[x<<1].r) return query(x<<1,p);
    	else return min(d[x<<1].val, query(x<<1|1,p));
    }
    int main(){
    	cin >> n >> q;
    	for (int i=1;i<=n;i++){
    		scanf("%d", a+i);
    		if (t.count(a[i])) p[++pl].L = t[a[i]], p[pl].R = i, t[a[i]] = i;
    		else t[a[i]] = i;
    	}
    	for (int i=1;i<=q;i++){
    		st[i].id = i;
    		scanf("%d%d",&st[i].l,&st[i].r);
    	}
    	sort(p+1,p+pl+1);
    	sort(st+1,st+q+1);
    	int pl1 = pl;
    	int pl2 = q;
    	build(1,1,n);
    	while (pl2 > 0){
    		while (p[pl1].L >= st[pl2].l) insert(1,p[pl1].R,p[pl1].R-p[pl1].L), pl1--;
    		ans[st[pl2].id] = query(1,st[pl2].r);
    		pl2 --;
    	}
    	for (int i=1;i<=q;i++){
    		printf("%d
    ",(ans[i]==0x3f3f3f3f?-1:ans[i]));
    	}
    }
    
  • 相关阅读:
    Hibernate
    Redis的学习
    Redis的人门以及使用
    Win32 配置文件用法
    Using virtual lists
    windows log
    Win查询注册表获取CPU与内存参数
    MFC 多线程及线程同步
    使用Custom Draw优雅的实现ListCtrl的重绘
    MFC工具栏设计
  • 原文地址:https://www.cnblogs.com/dgklr/p/11764926.html
Copyright © 2011-2022 走看看