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;
    }
    

      

  • 相关阅读:
    HTML基本知识
    几个常用的正则表达式
    C#操作文件
    传说中的WCF(3):多个协定
    传说中的WCF(2):服务协定的那些事儿
    查询表、存储过程、触发器的创建时间和最后修改时间
    SQL四舍五入及两种舍入
    自制 JS.format带分页索引
    js:字符串(string)转json
    $.each 和$(selector).each()的区别
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9781810.html
Copyright © 2011-2022 走看看