zoukankan      html  css  js  c++  java
  • [CF522D]Closest Equals

    题目大意:给一个区间,多次询问,每次问区间$[l,r]$里最近的两个相同的数的距离是多少。

    题解:用一个数组$pre_i$表示第$i$个数前面最近的一个相同的数在哪,询问变成了询问$[l,r]$中$i-pre_i$的最小值,且$pre_iin[l,r]$。难度就在处理$pre_i otin[l,r]$上。

    $$
    ecause pre_i<i,iin[l,r]\
    herefore pre_i<r\
    若pre_i otin[l,r]\
    则pre_i<l
    $$

    这题没有修改,可以把询问按$l$排序,把不合法的点贡献去掉

    卡点:$map$没更新

    C++ Code:

    #include <cstdio>
    #include <algorithm>
    #include <map>
    #define maxn 500010
    const int inf = 0x3f3f3f3f;
    inline int min(int a, int b) {return a < b ? a : b;}
    
    int a[maxn], pre[maxn], nxt[maxn];
    std::map<int, int> mp;
    struct Query {
    	int l, r, id;
    	inline bool operator < (const Query &rhs) const {return l < rhs.l;}
    } Q[maxn];
    int ans[maxn];
    
    int V[maxn << 2];
    inline void update(int rt) {
    	V[rt] = min(V[rt << 1], V[rt << 1 | 1]);
    }
    void build(int rt, int l, int r) {
    	if (l == r) {
    		if (pre[l]) V[rt] = l - pre[l];
    		else V[rt] = inf;
    		return ;
    	}
    	int mid = l + r >> 1;
    	build(rt << 1, l, mid);
    	build(rt << 1 | 1, mid + 1, r);
    	update(rt);
    }
    void modify(int rt, int l, int r, int p) {
    	if (l == r) {
    		V[rt] = inf;
    		return ;
    	}
    	int mid = l + r >> 1;
    	if (p <= mid) modify(rt << 1, l, mid, p);
    	else modify(rt << 1 | 1, mid + 1, r, p);
    	update(rt);
    }
    int query(int rt, int l, int r, int L, int R) {
    	if (L <= l && R >= r) return V[rt];
    	int mid = l + r >> 1, ans = inf;
    	if (L <= mid) ans = query(rt << 1, l, mid, L, R);
    	if (R > mid) ans = min(ans, query(rt << 1 | 1, mid + 1, r, L, R));
    	return ans;
    }
    
    int n, m;
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; i++) {
    		scanf("%d", a + i);
    		if (mp.count(a[i])) pre[i] = mp[a[i]], nxt[mp[a[i]]] = i, mp[a[i]] = i;
    		else pre[i] = 0, mp[a[i]] = i;
    	}
    	for (int i = 1; i <= m; i++) {
    		scanf("%d%d", &Q[i].l, &Q[i].r);
    		Q[i].id = i;
    	}
    	std::sort(Q + 1, Q + m + 1);
    	build(1, 1, n);
    	int last = 1;
    	for (int i = 1; i <= m; i++) {
    		int l = Q[i].l;
    		for (; last < l; last++) {
    			if (nxt[last] >= l) modify(1, 1, n, nxt[last]);
    		}
    		ans[Q[i].id] = query(1, 1, n, l, Q[i].r);
    	}
    	for (int i = 1; i <= m; i++) if (ans[i] != inf) printf("%d
    ", ans[i]);
    	else puts("-1");
    	return 0;
    }
    

      

  • 相关阅读:
    dubbo入门(一)
    java中文件操作《一》
    Unity 游戏框架搭建 2019 (七) 自定义快捷键
    凉鞋:我所理解的框架 【Unity 游戏框架搭建】
    Unity 游戏框架搭建 2019 (六) MenuItem 复用
    Unity 游戏框架搭建 2019 (五) 打开所在文件夹
    Unity 游戏框架搭建 2019 (四) 导出 UnityPackage
    Unity 游戏框架搭建 2019 (三) 生成文件名到剪切板
    Unity 游戏框架搭建 2019 (二) 文本复制到剪切板
    Unity 游戏框架搭建 2019 (一) 简介与第一个示例文件名的生成
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9781810.html
Copyright © 2011-2022 走看看