[伯俊]#18119単語暗記



質問する


俊碩は英語の単語を暗記しなければならない.辞書にはN語ある.すべての単語は小文字です.単語のすべてのアルファベットを知っていると、その単語を完全に知っていると言います.
次のクエリが表示されます.
  • 1 x:アルファベットを忘れるx
  • 2 x:アルファベットxを覚える.
    最初はすべてのアルファベットを覚えた状態で、母音は完璧に暗記されているので、絶対に忘れません.
  • 各クエリーは、完全に知っている単語の数を出力します.

    入力


    1行目は整数N(1≦N≦104)とM(1≦M≦5)である.×104).
    次のN行に文字列があります.文字列の長さは103を超えない.
    次のM行の整数oと文字xの各行.oは1,2の1つで、xは小文字です.
    oが1であればxを忘れることを意味し、oは2を覚えることを意味する.oが1の場合はxを覚え、oが2の場合はxを忘れることを保証します.

    しゅつりょく


    クエリーごとに整数を出力します.

    入力例1

    5 10
    apple
    actual
    banana
    brick
    courts
    1 l
    1 b
    1 c
    1 n
    2 l
    2 b
    1 s
    2 c
    2 s
    2 n

    サンプル出力1

    3
    1
    0
    0
    1
    1
    1
    3
    4
    5

    に答える


    この問題はビットマスクで解くことができる.
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    
    public class Main {
    
        public static void main(String[] args) throws Exception{
    
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String[] input = br.readLine().split(" ");
            int N = Integer.parseInt(input[0]);
            int M = Integer.parseInt(input[1]);
            StringBuilder sb = new StringBuilder();
    
            int know = (1<<26)-1;   //처음에는 모든 알파벳을 알기 때문에 26자리를 1로 모두 채움
    
            int[] words = new int[N];
            for(int i=0; i<N; i++) {        //알파벳이 존재하면 해당 자릿수에 1
                int binary = 0;
    
                String str = br.readLine();
                for(int j=0; j<str.length(); j++) {
                    char x = str.charAt(j);
                    int y = (1<<(x-'a'));     //0~25 26개의 알파벳, 자리수 만큼 쉬프트 연산
                    binary |= y;
    
                    words[i] = binary;
                }
            }
    
            for(int i=0; i<M; i++) {
                input = br.readLine().split(" ");
                int o = Integer.parseInt(input[0]);
                int x = input[1].charAt(0) - 'a';
                int cnt = N;
    
                if(o==1)
                    know -= (1<<x);     //알파벳을 잊으면 알고있는 2진수에서 해당 자리 0으로 바꿈
    
                else
                    know += (1<<x);     //알파벳을 기억해내면 알고있는 2진수에서 해당 자리 1으로 바꿈
    
                for(int j=0; j<N; j++) {
                    int word = words[j];
    
                    if((word&know) != word)   //And 연산 후 숫자가 해당 단어랑 다를 경우 갯수 카운트에서 1씩 빼줌
                        cnt--;
                }
    
                sb.append(cnt).append("\n");
            }
    
            System.out.print(sb.toString());
        }
    }