uva12096 - The SetStack Computer

链接

https://vjudge.net/problem/UVA-12096

题解

用哈希骗过去了…
一开始写了个很慢的 s e t < s t r i n g > set<string> set<string>
想一想其实可能存在这样的数据:
PUSH
DUP
ADD
DUP
ADD
DUP
ADD
…以此类推
这样的话,字符串的长度是呈指数式增长的
但是集合的大小却不会增长的非常快
我搞了一个这样的玩意出来:
把每种出现过的集合映射到一个整数
空集映射到 1 1 1
对于非空集合,先把其元素的哈希值按照大小排序,然后形成一个 b a s e base base进制数字,把这个数字的值对 1 0 9 + 7 10^9+7 109+7取模,再 + 1 +1 +1,得到这个集合的哈希值
+ 1 +1 +1是为了区分 { } \{\} {} { { } } \{\{\}\} {{}}这两种情况
先用 s t a c k < s e t < i n t > > stack< set< int > > stack<set<int>>来维护,当一个 A D D ADD ADD操作出现时,一个 s e t < i n t > set<int> set<int>就会被我变成哈希值然后存到另一个 s e t set set中去

代码

#include 
#define base 4894651ll
#define mod 1000000007ll
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
    ll c, f=1;
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-48;
    return f*x;
}
ll get_hash(set<ll>& S)
{
    if(S.empty())return 1;
    ll result=0;
    for(auto x : S)
    {
        result = (result * base + x) % mod;
    }
    result = (result+1)%mod;
    return result;
}
int main()
{
    ll T=read(), N;
    string s;
    while(T--)
    {
        stack< set<ll> > stk;
        N=read();
        while(N--)
        {
            cin>>s;
            if(s=="PUSH")
            {
                set<ll> tmp;
                stk.emplace(tmp);
            }
            else if(s=="DUP")
            {
                auto tmp = stk.top();
                stk.emplace(tmp);
            }
            else if(s=="UNION")
            {
                auto tmp1=stk.top(); stk.pop();
                auto tmp2=stk.top(); stk.pop();
                set<ll> tmp3;
                for(auto x : tmp1)tmp3.emplace(x);
                for(auto x : tmp2)tmp3.emplace(x);
                stk.emplace(tmp3);
            }
            else if(s=="INTERSECT")
            {
                auto tmp1=stk.top(); stk.pop();
                auto tmp2=stk.top(); stk.pop();
                set<ll> tmp3;
                for(auto x : tmp1)if(tmp2.find(x)!=tmp2.end())tmp3.emplace(x);
                stk.emplace(tmp3);
            }
            else
            {
                auto tmp1=stk.top(); stk.pop();
                auto tmp2=stk.top(); stk.pop();
                tmp2.emplace(get_hash(tmp1));
                stk.emplace(tmp2);
            }
            cout<<stk.top().size()<<endl;
        }
        cout<<"***"<<endl;
    }
    return 0;
}

你可能感兴趣的:(c++のSTL)