zoukankan      html  css  js  c++  java
  • 【39.68%】【CF 714 C】Filya and Homework

    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Today Sonya learned about long integers and invited all her friends to share the fun. Sonya has an initially empty multiset with integers. Friends give her t queries, each of one of the following type:

    1.  +  ai — add non-negative integer ai to the multiset. Note, that she has a multiset, thus there may be many occurrences of the same integer.
    2.  -  ai — delete a single occurrence of non-negative integer ai from the multiset. It's guaranteed, that there is at least one ai in the multiset.
    3. ? s — count the number of integers in the multiset (with repetitions) that match some pattern s consisting of 0 and 1. In the pattern,0 stands for the even digits, while 1 stands for the odd. Integer x matches the pattern s, if the parity of the i-th from the right digit in decimal notation matches the i-th from the right digit of the pattern. If the pattern is shorter than this integer, it's supplemented with0-s from the left. Similarly, if the integer is shorter than the pattern its decimal notation is supplemented with the 0-s from the left.

    For example, if the pattern is s = 010, than integers 92221250 and 414 match the pattern, while integers 311025 and 1030 do not.

    Input

    The first line of the input contains an integer t (1 ≤ t ≤ 100 000) — the number of operation Sonya has to perform.

    Next t lines provide the descriptions of the queries in order they appear in the input file. The i-th row starts with a character ci — the type of the corresponding operation. If ci is equal to '+' or '-' then it's followed by a space and an integer ai (0 ≤ ai < 1018) given without leading zeroes (unless it's 0). If ci equals '?' then it's followed by a space and a sequence of zeroes and onse, giving the pattern of length no more than 18.

    It's guaranteed that there will be at least one query of type '?'.

    It's guaranteed that any time some integer is removed from the multiset, there will be at least one occurrence of this integer in it.

    Output

    For each query of the third type print the number of integers matching the given pattern. Each integer is counted as many times, as it appears in the multiset at this moment of time.

    Examples
    input
    12
    + 1
    + 241
    ? 1
    + 361
    - 241
    ? 0101
    + 101
    ? 101
    - 101
    ? 101
    + 4000
    ? 0
    
    output
    2
    1
    2
    1
    1
    
    input
    4
    + 200
    + 200
    - 200
    ? 0
    
    output
    1
    
    Note

    Consider the integers matching the patterns from the queries of the third type. Queries are numbered in the order they appear in the input.

    1. 1 and 241.
    2. 361.
    3. 101 and 361.
    4. 361.
    5. 4000.

    【题解】

    给你一个01串。从右到左对应了每个位置上的要求:0该位置为偶数。1该位置为奇数.

    如果01串和要判断的数字不一样。谁短谁前面就补0;

    我们不管谁短。直接在输入的数字前面补0至18位就好。

    然后用字典树来操作。

    插入数字的时候。不要具体记录这个数字是什么(没用!),只要知道这个数字是奇数还是偶数就行了嘛。所以93432你就记录11010.

    不要被惯性思维影响!

    直接记录数字会T!


    然后字典树的域要记录以这个节点为终点的数字个数。

    每次到这个节点累加这个就可以了。

    【代码】

    #include <cstdio>
    #include <cstring>
    
    
    using namespace std;
    
    const int MAX_SIZE = 2000000;
    
    int t;
    int tree[MAX_SIZE][2] = { 0 },totn = 0,ans = 0;
    int e[MAX_SIZE] = { 0 }, stop[MAX_SIZE] = { 0 };
    char op[5], dig[30];
    
    void insert()
    {
    	int temp = 0;
    	int len = 18;
    	for (int i = len-1; i >=0; i--)
    	{
    		int d = dig[i] - '0';
    		d = d % 2;//直接记录是奇数还是偶数就可以了。
    		if (tree[temp][d] == 0)
    			tree[temp][d] = ++totn;
    		temp = tree[temp][d];
    		stop[temp]++;
    	}
    	e[temp]++;
    }
    
    void de_lete()
    {
    	int temp = 0;
    	int len = 18;
    	for (int i = len-1; i >=0; i--)
    	{
    		int d = dig[i] - '0';
    		d = d % 2;
    		temp = tree[temp][d];
    		stop[temp]--;
    	}
    	e[temp]--;
    }
    
    void dfs(int rt, int len) //用dfs来累加答案。
    {
    	ans += e[rt];
    	if (len < 0)
    		return;
    	int d = dig[len] - '0';
    		if (tree[rt][d])
    				dfs(tree[rt][d], len - 1);
    
    }
    
    void get_ans()
    {
    	int temp = 0;
    	int len = 18;
    	dfs(temp, len - 1);
    }
    
    void input_data()
    {
    	scanf("%d", &t);
    	char s1[30];
    	for (int i = 1; i <= t; i++)
    	{
    		scanf("%s%s", op, s1);
    		int len = strlen(s1);
    		for (int i = 0; i <= 18 - len - 1; i++)//补零
    			dig[i] = '0';
    		dig[18 - len] = '';
    		strcat(dig, s1);//最后dig记录的是补0后的字符
    		if (op[0] == '+')
    			insert();
    		else
    			if (op[0] == '-')
    				de_lete();
    			else
    			{
    				ans = 0;
    				get_ans();
    				printf("%d
    ", ans);
    			}
    	}
    }
    
    int main()
    {
    	//freopen("F:\rush.txt", "r", stdin);
    	input_data();
    	return 0;
    }






  • 相关阅读:
    Codeforces Round #592 (Div. 2)C. The Football Season(暴力,循环节)
    Educational Codeforces Round 72 (Rated for Div. 2)D. Coloring Edges(想法)
    扩展KMP
    poj 1699 Best Sequence(dfs)
    KMP(思路分析)
    poj 1950 Dessert(dfs)
    poj 3278 Catch That Cow(BFS)
    素数环(回溯)
    sort与qsort
    poj 1952 buy low buy lower(DP)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632246.html
Copyright © 2011-2022 走看看