Luo Gu P1972 [SDOI2009] HH necklace

Topic
today review Fenwick tree, Qiaowan templates wrote this question. I waited a long time is facing the problem would like to think this problem and Fenwick tree have anything to do, even if it is kept this bit value, so we are unable to transfer back. . . .

After the meditation, try to do offline on line ordering violence, T to mother did not know. . .

Then open the skilful solution to a problem, some research. It found that in addition to the off-line ordering, as well as mystery. Key to this question lies in the statistics for each point in front of a tree with an array of contributions . Unexpectedly, this should also be a way of thinking of this question right angle array solution in a tree. Consider the contribution of elements on the directional range of this angle is really quite common, so write a blog summarize records.

Specific ideas:
the contribution of adding directional range Fenwick tree representation, the number of elements in the array of new elements contribute to its front section. Plainly something, in front of this element, the position is 1 0 otherwise.

Dealing with all sections of the first reading, do offline processing in accordance with the right end of the sort. Followed by a maintenance element of the array subscripts r, r to the traversal section elements within the new segment added Fenwick tree maintenance. When adding Fenwick tree, consider whether the element appeared in front, if there have been, the previous location of the deletion of contribution, contribution instead of the point.

As a result, from the first element to the current range of endpoints within this range ensures that the contribution of all of the same elements are from the rightmost generated . Then, after completing maintenance, just to the current range of l to r and contribution to the interval of.

Mix c and c ++ style AC codes;

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1000050;
int a[N];
int num[N];
int pos[N];
int ans[N];
int n,m;

struct node
{
    int l;
    int r;
    int code;
}b[N];

int lowBit(int k)
{
    return k & (-k);
}

int cmp(node a,node b)
{
    return a.r < b.r;
}

void add(int k,int num)
{
    while(k <= n)
    {
        a[k] += num;
        k += lowBit(k);
    }
}

int get(int k)
{
    int sum = 0;
    while(k)
    {
        sum += a[k];
        k -= lowBit(k);
    }
    return sum;
}

int main()
{

    scanf("%d",&n);
    for(int i = 1;i <= n;i++)
    {
        scanf("%d",&num[i]);
    }
    scanf("%d",&m);
    for(int i = 0;i < m;i++)
    {
        scanf("%d%d",&b[i].l,&b[i].r);
        b[i].code = i;
    }
    sort(b,b + m,cmp);
    int r = 0;
    node v;
    for(int i = 0;i < m;i++)
    {
        v = b[i];
        while(r < v.r)
        {
            r++;
            if(pos[num[r]])
            {
                add(pos[num[r]],-1);
            }
            pos[num[r]] = r;
            add(pos[num[r]],1);
        }
        ans[v.code] = get(v.r) - get(v.l - 1);
    }
    for(int i = 0;i < m;i++)
    {
        printf("%d\n",ans[i]);
    }
}

T to doubt correct but life java code:

import java.util.Arrays;
import java.util.Scanner;

class s implements Comparable<s>
{
	int l;
	int r;
	int code;
	public s(int l, int r, int code) 
	{
		this.l = l;
		this.r = r;
		this.code = code;
	}
	public int  compareTo(s o)
	{
		return r - o.r;
	}
}

class TreeArray {
	private int[] array;
	private int size;
	
	public TreeArray(int n)
	{
		size = n;
		array = new int[n + 1];
	}
	
	private int lowBit(int k)
	{
		return k & (-k);
	}
	
	public void add(int k,int num)
	{
		while(k <= size)
		{
			array[k] += num;
			k += lowBit(k);
		}
	}
	
	public int get(int k)
	{
		int sum = 0;
		while(k > 0)
		{
			sum += array[k];
			k -= lowBit(k);
		}
		return sum;
	}
	
	public int get(int l,int r)
	{
		return get(r) - get(l - 1);
	}
}

public class Main {
	static int[] num = new int[1000050];
	static int[] ans = new int[1000050];
	static int[] c = new int[1000050];
	static s[] a;
	public static void main(String[] args)
	{
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt();
		for(int i = 1;i <= n;i++)
		{
			num[i] = scan.nextInt();
		}
		int m = scan.nextInt();
		a = new s[m];
		for(int i = 0;i < m;i++)
		{
			a[i] = new s(scan.nextInt(),scan.nextInt(),i);
		}
		Arrays.sort(a);
		s v;
		TreeArray ta = new TreeArray(n);
		int r = 0;
		for(int i = 0;i < m;i++)
		{
			v = a[i];
			while(r < v.r) 
			{
				r++;
				if(c[num[r]] != 0)
				{
					ta.add(c[num[r]], -1);
				}
				ta.add(r, 1);
				c[num[r]] = r;
			}
			ans[v.code] = ta.get(v.l,v.r);
		}
		for(int i = 0;i < m;i++)
		{
			System.out.println(ans[i]);
		}
	}
}

Published 17 original articles · won praise 2 · Views 460

Guess you like

Origin blog.csdn.net/wayne_lee_lwc/article/details/104680624