zoukankan      html  css  js  c++  java
  • SPOJ 3267 DQUERY

    题目大意

    对于一个数列 (left{a_n ight}) , 有 (q) 次询问,第 (i) 次询问格式为 (l_i,r_i) , 求 (a_{l_i},a_{l_i + 1},a_{l_i + 2},dots,a_{r_i}) 中有多少不同的数。
    其中, (1 leq n leq 3 imes 10^4)(1 leq q leq 2 imes 10^5)(1 leq a_i leq 10^6)

    题解

    (n) 棵主席树,第 (i) 棵主席树记录前 (i) 个位置的状态。
    在进行 Insert 操作时,如果 (a_i) 在位置 (j) 出现过,那么位置 (i) 赋值为 (1) ,位置 (j) 赋值为 (0)
    即每次查询的答案为第 (r_i) 棵主席树中 ([l_i,r_i]) 的和。

    #include <cstdio>
    #include <algorithm>
    
    #define MAX_N (30000 + 5)
    #define MAX_A (1000000 + 5)
    #define MAX_SIZE 1020000
    
    using std::sort;
    
    struct Tree
    {
    	int size;
    	int l, r;
    };
    
    int n, q;
    int a[MAX_N];
    int h[MAX_A], nxt[MAX_N];
    int root[MAX_N], num;
    Tree s[MAX_SIZE];
    
    void Insert(int, int, int, int, int, int);
    int Query(int, int, int, int, int);
    
    int main()
    {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++i)
    	{
    		scanf("%d", &a[i]);
    		nxt[i] = h[a[i]];
    		h[a[i]] = i;
    	}
    	for (int i = 1; i <= n; ++i)
    	{
    		root[i] = ++num;
    		Insert(root[i - 1], root[i], 1, n, nxt[i], i);
    	}
    	scanf("%d", &q);
    	int l, r;
    	while (q--)
    	{
    		scanf("%d%d", &l, &r);
    		printf("%d
    ", Query(root[r], 1, n, l, r)); 
    	}
    }
    
    void Insert(int r1, int r2, int L, int R, int p1, int p2)
    {
    	if (L == R)
    	{
    		if (L == p1) s[r2].size = 0;
    		else s[r2].size = 1;
    		return;
    	}
    	int mid = L + R >> 1;
    	s[r2].l = s[r1].l;
    	s[r2].r = s[r1].r;
    	if (L <= p1 && p1 <= mid || L <= p2 && p2 <= mid)
    	{
    		s[r2].l = ++num;
    		Insert(s[r1].l, s[r2].l, L, mid, p1, p2);
    	}
    	if (mid + 1 <= p1 && p1 <= R || mid + 1 <= p2 && p2 <= R)
    	{
    		s[r2].r = ++num;
    		Insert(s[r1].r, s[r2].r, mid + 1, R, p1, p2);
    	}
    	s[r2].size = s[s[r2].l].size + s[s[r2].r].size;
    }
    
    int Query(int idx, int L, int R, int lt, int rt)
    {
    	if (R < lt || rt < L) return 0;
    	if (lt <= L && R <= rt) return s[idx].size;
    	int mid = L + R >> 1;
    	return Query(s[idx].l, L, mid, lt, rt) + Query(s[idx].r, mid + 1, R, lt, rt); 
    }
    
  • 相关阅读:
    MySQL 中随机抽样:order by rand limit 的替代方案
    mysql下distinct和group by区别对比
    MVC中实现多按钮提交(转)
    js的逻辑 OR 运算符- ||
    js 实现键盘记录 兼容FireFox和IE
    jquery扩展
    sp_executesql的用法
    MVC中,视图的Layout使用
    MVC4的过滤器
    MVC中的Repository模式
  • 原文地址:https://www.cnblogs.com/kcn999/p/13437508.html
Copyright © 2011-2022 走看看