http://codeforces.com/contest/714/problem/C
#include <bits/stdc++.h>//非递归形式建立字典树 using namespace std; #define ll long long #define dd double #define co(x) cout << (x) << endl #define ci(x) cin >> (x) #define sd(x) scanf("%d",&x) #define sl(x) scanf("%lld",&x) #define sf(x) scanf("%lf",&x) #define gcd(x,y) __gcd(x,y) #define fo(i,j,k) for(int (i) = (j); (i) < (k); (i)++) #define en cout << endl; #define Inf 2147483645 #define Maxn 100100 ll Node[Maxn*40][2];//存图 ll Nodesum[Maxn];//存那个节点有多少个满足条件的值 int num = 1;//num是节点序号 void Build(char c,ll k){//思路是把所有满足条件的都情况都在建图的时候放在图中 // 例如 +1101 先放1(就把满足+1的值放图中),然后放0,就把满足+10的条件放在图中,类推 // 就是字典树的套路,自己理解一下 int s = 0; for(int i = 0; i < 20; i++){ int a = k%2;//取最后一位,不满20位就补0,直到满20位, // (题目数据给的是10^18,最多18位,这里用20) if( !Node[s][a] ){ Node[s][a] = num++;//如果改节点没有建立,就给该节点 // 建立(即给该节点赋值,第num个节点) } if(c == '+'){ Nodesum[Node[s][a]]++; }else{ Nodesum[Node[s][a]]--; } s = Node[s][a]; k /= 10; } } int query(ll x){ int s = 0; for(int i = 0; i < 20; i++){ int a = x%2; if( Node[s][a] == 0 ){ return 0; } s = Node[s][a]; x /= 10; } return Nodesum[s]; } int main(){ ios::sync_with_stdio(false); cin.tie(0),cout.tie(0); int N; cin >> N; ll k; char c; for(int i = 0; i < N; i++){ cin >> c >> k; if( c != '?' ){ Build(c,k); }else{ cout << query(k) << endl; } } return 0; }