Submission #7489999


Source Code Expand

#include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;--i)
#define srep(i,s,t) for(int i=(int)(s);i<(int)(t);++i)
#define each(a,b) for(auto& (a): (b))
#define all(v) (v).begin(),(v).end()
#define len(v) (int)(v).size()
#define zip(v) sort(all(v)),v.erase(unique(all(v)),v.end())
#define cmx(x,y) x=max(x,y)
#define cmn(x,y) x=min(x,y)
#define fi first
#define se second
#define pb push_back
#define show(x) cout<<#x<<" = "<<(x)<<endl
#define sar(a,n) {cout<<#a<<":";rep(pachico,n)cout<<" "<<a[pachico];cout<<endl;}

using namespace std;

template<typename S,typename T>auto&operator<<(ostream&o,pair<S,T>p){return o<<"{"<<p.fi<<","<<p.se<<"}";}
template<typename T>auto&operator<<(ostream&o,set<T>s){for(auto&e:s)o<<e<<" ";return o;}
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,priority_queue<S,T,U>q){while(!q.empty())o<<q.top()<<" ",q.pop();return o;}
template<typename K,typename T>auto&operator<<(ostream&o,map<K,T>&m){for(auto&e:m)o<<e<<" ";return o;}
template<typename T>auto&operator<<(ostream&o,vector<T>v){for(auto&e:v)o<<e<<" ";return o;}
void ashow(){cout<<endl;}template<typename T,typename...A>void ashow(T t,A...a){cout<<t<<" ";ashow(a...);}
template<typename S,typename T,typename U>
struct TRI{S fi;T se;U th;TRI(){}TRI(S f,T s,U t):fi(f),se(s),th(t){}
bool operator<(const TRI&_)const{return(fi==_.fi)?((se==_.se)?(th<_.th):(se<_.se)):(fi<_.fi);}};
template<typename S,typename T,typename U>
auto&operator<<(ostream&o,TRI<S,T,U>&t){return o<<"{"<<t.fi<<","<<t.se<<","<<t.th<<"}";}

typedef pair<int, int> P;
typedef pair<ll, ll> pll;
typedef TRI<int, int, int> tri;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<P> vp;
typedef vector<double> vd;
typedef vector<string> vs;

const int MAX_N = 100005;

// 使う文字は 31 文字以下の文字コード上で連続する文字の列とする.
template<unsigned int CHARACTER_SIZE, char START_CHARACTER>
class CompressedTrie {
private:
    struct node {
        string *s;
        node **to;
        // sub: 部分木に含まれる要素の数, adj: 子の bit 表現
        uint32_t sub, adj;
        node() : s(nullptr), to(nullptr),  sub(1u), adj(0u){}
        node(string&& _s, node *v, unsigned int index, uint32_t _sub)
         : s(new string[CHARACTER_SIZE]()), to(new node*[CHARACTER_SIZE]()),
            sub(_sub), adj(1u << index){
            s[index] = move(_s), to[index] = v;
        }
        // ~node(){ delete[] s, delete[] to; }
        #define lsb(v) (__builtin_ctz(v))
        inline unsigned int begin() const { return adj ? lsb(adj) : CHARACTER_SIZE; }
        inline unsigned int next(unsigned int cur) const {
            cur = adj & ~((1u << (cur + 1u)) - 1u);
            return cur ? lsb(cur) : CHARACTER_SIZE;
        }
        inline static unsigned int end(){ return CHARACTER_SIZE; }
        inline bool isExist(const unsigned int v) const { return adj >> v & 1u; }
        inline bool isFinal() const { return !s; }
        void direct_push(string&& _s, unsigned int index){
            if(!s) s = new string[CHARACTER_SIZE](), to = new node*[CHARACTER_SIZE]();
            s[index] = move(_s), to[index] = new node(), ++sub, adj |= (1u << index);
        }
    };
    void make_node(string& orgs, unsigned int start, node*& to){
        string tmp = orgs.substr(0, start);
        orgs.erase(orgs.begin(), orgs.begin() + start);
        to = new node(move(orgs), to, orgs[0] - START_CHARACTER, to->sub);
        orgs = move(tmp);
    }
    void new_push(const string& s, unsigned int index, node *to){
        string _s(s.substr(index, s.size() - index));
        to->direct_push(move(_s), s[index] - START_CHARACTER);
    }
    void new_push(string&& s, unsigned int index, node *to){
        s.erase(s.begin(), s.begin() + index);
        to->direct_push(move(s), s[0] - START_CHARACTER);
    }
    template<typename String>
    void push(node *cur, String&& news){
        const unsigned int _ls = news.size();
        unsigned int index = 0u, prefix;
        while(true){
            const unsigned int num = news[index] - START_CHARACTER;
            if(cur->isExist(num)){
                ++cur->sub;
                string& orgs = cur->s[num];
                const unsigned int ls = orgs.size();
                for(prefix = 0u; prefix < ls && index < _ls; ++prefix, ++index){
                    if(orgs[prefix] == news[index]) continue;
                    make_node(orgs, prefix, cur->to[num]);
                    new_push(forward<String>(news), index, cur->to[num]);
                    return;
                }
                if(index == _ls){
                    if(prefix == ls) return;
                    make_node(orgs, prefix, cur->to[num]);
                    return;
                }else{
                    cur = cur->to[num];
                }
            }else{
                new_push(forward<String>(news), index, cur);
                return;
            }
        }
    }
    // void clear_dfs(node *cur){
    //     if(!cur) return;
    //     for(unsigned int i = 0u; i < CHARACTER_SIZE; ++i) if(cur->to) clear_dfs(cur->to[i]);
    //     delete cur;
    // }
public:
    node* root;
    CompressedTrie() : root(new node()){}
    // ~CompressedTrie(){ clear_dfs(root); }
    // CompressedTrie 木に s を加える
    void add(const string& s){ push(root, s); }
    void add(string&& s){ push(root, move(s)); }
    //何らかのクエリ
    int recur_query(node *cur, unsigned int d, int *index, const string& s){
        int res = 0;
        while(true){
            if(cur->isFinal()) break;
            const unsigned int next = s[d] - START_CHARACTER;
            for(unsigned int i = cur->begin(); i != cur->end(); i = cur->next(i)){
                if(index[i] < index[next]) res += cur->to[i]->sub;
            }
            d += cur->s[next].size();
            cur = cur->to[next];
        }
        return res;
    }
    int query(int *index, const string& s){
        return recur_query(root, 0u, index, s);
    }
};

string s[MAX_N];
int id[27];
const char c = (char)('z' + 1);

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    CompressedTrie<27, 'a'> pt;
    rep(i, n){
        cin >> s[i];
        s[i].push_back(c);
        pt.add(s[i]);
    }
    int q;
    cin >> q;
    rep(i, q){
        int k;
        string t;
        cin >> k >> t;
        rep(j, 26) id[(int)(t[j] - 'a')] = j + 1;
        id[26] = 0;
        cout << pt.query(id, s[k-1]) + 1 << "\n";
    }
    return 0;
}

Submission Info

Submission Time
Task E - Lexicographical disorder
User kopricky
Language C++14 (GCC 5.4.1)
Score 1100
Code Size 6898 Byte
Status AC
Exec Time 1095 ms
Memory 27264 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 1100 / 1100
Status
AC × 2
AC × 42
Set Name Test Cases
Sample s1.txt, s2.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, 38.txt, 39.txt, 40.txt, s1.txt, s2.txt
Case Name Status Exec Time Memory
01.txt AC 179 ms 27264 KiB
02.txt AC 172 ms 27136 KiB
03.txt AC 182 ms 27136 KiB
04.txt AC 175 ms 27136 KiB
05.txt AC 126 ms 14592 KiB
06.txt AC 83 ms 3712 KiB
07.txt AC 70 ms 2944 KiB
08.txt AC 61 ms 2560 KiB
09.txt AC 52 ms 2304 KiB
10.txt AC 39 ms 2216 KiB
11.txt AC 128 ms 16256 KiB
12.txt AC 119 ms 19840 KiB
13.txt AC 130 ms 22784 KiB
14.txt AC 74 ms 4736 KiB
15.txt AC 47 ms 2688 KiB
16.txt AC 41 ms 2088 KiB
17.txt AC 37 ms 2204 KiB
18.txt AC 1060 ms 2816 KiB
19.txt AC 1080 ms 2816 KiB
20.txt AC 1095 ms 2816 KiB
21.txt AC 1075 ms 2816 KiB
22.txt AC 1087 ms 2816 KiB
23.txt AC 117 ms 21888 KiB
24.txt AC 123 ms 16384 KiB
25.txt AC 126 ms 19968 KiB
26.txt AC 1038 ms 2816 KiB
27.txt AC 75 ms 4096 KiB
28.txt AC 72 ms 4480 KiB
29.txt AC 60 ms 2560 KiB
30.txt AC 98 ms 9216 KiB
31.txt AC 67 ms 2816 KiB
32.txt AC 47 ms 2176 KiB
33.txt AC 42 ms 2048 KiB
34.txt AC 44 ms 2048 KiB
35.txt AC 45 ms 2048 KiB
36.txt AC 171 ms 23808 KiB
37.txt AC 39 ms 2068 KiB
38.txt AC 39 ms 2068 KiB
39.txt AC 2 ms 1024 KiB
40.txt AC 2 ms 1024 KiB
s1.txt AC 2 ms 1024 KiB
s2.txt AC 2 ms 1024 KiB