Problem:
Multi-Set

For a set $S$ of integers, perform a sequence of the following operations. Note that multiple elements can have equivalent values in $S$.

insert($x$): Insert $x$ to $S$ and report the number of elements in $S$ after the operation.

find($x$): Report the number of $x$ in $S$.

delete($x$): Delete all $x$ from $S$.

dump($L$, $R$): Print elements $x$ in $S$ such that $L \leq x \leq R$.

Input

The input is given in the following format.

$q$
$query_1$
$query_2$
:
$query_q$

Each query $query_i$ is given by

0 $x$

or

1 $x$

or

2 $x$

or

3 $L$ $R$

where the first digits 0, 1, 2 and 3 represent insert, find, delete and dump operations respectively.

Output

For each insert operation, print the number of elements in $S$.

For each find operation, print the number of specified elements in $S$.

For each dump operation, print the corresponding elements in ascending order. Print an element in a line.

Constraints

$1 \leq q \leq 200,000$

$0 \leq x \leq 1,000,000,000$

The total number of elements printed by dump operations does not exceed $1,000,000$

The sum of numbers printed by find operations does not exceed $2,000,000$

Sample Input 1

10
0 1
0 1
0 2
0 3
2 2
1 1
1 2
1 3
0 4
3 1 4

Sample Output 1

1
2
3
4
2
0
1
4
1
1
3
4

Solution in JAVA (judge verdict: Wrong Answer)


import java.io.*;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner in=new Scanner (System.in);
        Mymset mset=new Mymset();
        int q=Integer.parseInt(in.next());
        for(int i=0;i<q;i++) {
            int odr=Integer.parseInt(in.next());
            switch(odr) {
            case 0:
            	System.out.println(mset.insert(Integer.parseInt(in.next())));
            	break;
            	
            case 1:
            	System.out.println(mset.find(Integer.parseInt(in.next())));
            	break;
            	
            case 2:
            	mset.removeOf(Integer.parseInt(in.next()));
            	break;
            	
            case 3:
            	mset.dump(Integer.parseInt(in.next()),Integer.parseInt(in.next()));
            	break;
            }
        }
    }

}

class Bnode{
    int v,num;
    Bnode p,l,r;


    Bnode(int v,int num){
        this.v=v;
        this.num=num;
    }
}

class Mymset{
    Bnode root,dummy,NOW;
    int size;
    PrintWriter out=new PrintWriter(System.out);
    
    Mymset(){
        dummy=new Bnode(-1,-1);
        dummy.p=dummy; dummy.l=dummy; dummy.r=dummy;
        init();
        size=0;
    }

    void init() {
        root=dummy;
    }

    int insert(int x) {
        Bnode NEW=new Bnode(x,1);
        NEW.l=dummy;NEW.r=dummy;
        if(size==0) {
            root=NEW;
            root.p=dummy;
        }
        else {
            //Bnode NOW=root;
            NOW=root;
            while(true) {
            	if(NOW.v==NEW.v) {
                    NOW.num++;
                    break;
                }
            	else if(NEW.v>NOW.v) {
                    if(NOW.r.v==-1) {
                        NOW.r=NEW;
                        NEW.p=NOW;
                        break;
                    }
                    else NOW=NOW.r;
                }
                else {
                    if(NOW.l.v==-1) {
                        NOW.l=NEW;
                        NEW.p=NOW;
                        break;
                    }
                    else NOW=NOW.l;
                }
            }
        }
        size++;
        return size;
    }

    void removeOf(int x){
    	find(x);
    	int n=NOW.num;
    	if(NOW.r.v==-1 && NOW.l.v==-1){
    		if(NOW.p.l==NOW)NOW.p.l=dummy;
    		else NOW.p.r=dummy;
    	}
    	else if(NOW.r.v!=-1 || NOW.l.v!=-1) {
    		if(NOW.p.r==NOW) {
    			NOW.p.r=NOW.r;
    			NOW.r.p=NOW.p;
    		}
    		else {
    			NOW.p.l=NOW.l;
    			NOW.l.p=NOW.p;
    		}
    	}
    	else {
    		Bnode y=findNextNode(NOW.r);
    		NOW.v=y.v;
    		NOW.num=y.num;
    		if(y.r.v==-1 && y.l.v==-1){
        		if(y.p.l==y)y.p.l=dummy;
        		else y.p.r=dummy;
        	}
        	else if(y.r.v!=-1 || y.l.v!=-1) {
        		if(y.p.r==y) {
        			y.p.r=y.r;
        			y.r.p=y.p;
        		}
        		else {
        			y.p.l=y.l;
        			y.l.p=y.p;
        		}
        	}
    	}
    	size-=n;
    }
    
    
    Bnode findNextNode(Bnode node) {
    	if(node.l.v!=-1)return findNextNode(node.l);
    	else return node;
    }

    int find(int x){
        NOW=root;
        while(NOW.v!=-1) {

            if(NOW.v==x)break;
            else if(NOW.v>x)NOW=NOW.l;
            else NOW=NOW.r;
        }
        return (NOW.num>0)?NOW.num : 0;
    }

    void dump(int L,int R) {
        inwalk(root,L,R);
        out.flush();
    }

    void inwalk(Bnode now,int L,int R) {
        if(now.v>=L && now.v<=R) {
        	if(now.l.v!=-1)inwalk(now.l,L,R);
            System.out.println(now.v);
            if(now.r.v!=-1)inwalk(now.r,L,R);
        }
    }

}