sgu 552 Database Optimization

来源:互联网 发布:网络英语学习平台 编辑:程序博客网 时间:2024/06/12 18:40
Alex worked at a big IT-company called Macrohard. Once, when he faced a large amount of data, he decided to leave this company and develop his own database which would be much better than all existing ones. When he was done with this he realized that the performance of some database queries might be improved. Alex uses AQL (Alex Query Language) which accidentally turned out to be exactly the same as the popular SQL. One of the most important problems he faced was the following.

Consider n objects. The i-th object has ki (1 ≤ ki ≤ 4) properties in the form of 
key=value
. Any object can't have two or more properties with the same key. Alex needs to improve the performance of the following query:

SELECT COUNT(*) FROM Objects WHERE key1=value1 AND...  AND keyl=valuel
 
(1 ≤ l ≤ 4, all keys are distinct)
This means that Alex's database has to find the number of objects which have properties key1key2,..., keylwith the values value1value2,..., valuel respectively. Even if an object has extra properties it should be counted.

Your task is to help Alex to write an efficient program to process such queries.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 5 · 104) — the number of objects. Following n lines describe objects by their properties. Each line contains the integer ki (1 ≤ ki ≤ 4) followed by ki tokens in the form of keyi,j=valuei,j separated by a single space. Both keyi,j and valuei,j consist of digits and lowercase Latin letters. The keyi,j are distinct for each object. It is possible that different objects have exactly the same set of properties.

The next line of the input contains a single integer m (1 ≤ m ≤ 105) — the number of queries. The following mlines describe the queries. Each line contains a single integer li (the number of properties that describe the i-th query) followed by li (1 ≤ li ≤ 4) tokens keyi,j=valuei,j separated by a single space, where keyi,j and valuei,jconsist of digits and lowercase Latin letters. The keyi,j are distinct for each query.

Lengths of keyi,j and valuei,j both for objects and queries are between 1 and 5 characters inclusive.

Output

Print m lines, the i-th line should contain the result of the i-th query. 

Sample Input

Example(s)
sample input
sample output
43 width=5 ht=3 len=102 name=circ rad=52 name=circ rad=53 name=sqr width=5 ht=342 ht=3 width=51 name=circ1 name=sqr2 width=5 ht=03
2210

题意 :   给n个关键字 , 然后再给m个关键字是可以任意组合在一起的,问,能在n个关键字(每行也可以任意组合在一起)里 查询出多少个 .



#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
#include <map> 
using namespace std;


map<string,int>mp;


int N, M;
string str[4];       //  每个元素 是一个字符串 .


int main() {
    while (cin >> N) {
        int x;
        mp.clear();                            //初始化,清空map
        for (int i = 0; i < N; ++i) {
            cin >> x;
            for (int j = 0; j < x; ++j) {
                cin >> str[j];
            }
            sort(str, str+x);               //升序排序
            int mask = 1 << x;              //利用二进制枚举所有的关键字的组合.
            for (int j = 0; j < mask; ++j) {
                string tmp;
                for (int k = 0; k < 4; ++k) {
                    if (j & (1 << k)) {
                        tmp += " " + str[k];
                    }
                }
                ++mp[tmp];                  //得到的一个组合,数量加1
            }
        }
        cin >> M;
        while (M--) {
            cin >> x;
            for (int i = 0; i < x; ++i) {
                cin >> str[i];
            }
            sort(str, str+x);                         //要查询的关键字 也升序排序
            string tmp;
            for (int i = 0; i < x; ++i) {
                tmp += " " + str[i];            
            }
            printf("%d\n", mp[tmp]);                   //直接查找,这个组合的关键字有多少个
        }
    }
    return 0;
}


 . .

原创粉丝点击