Submission #109197

# Submission time Handle Problem Language Result Execution time Memory
109197 2019-05-05T12:19:12 Z popovicirobert Selling RNA Strands (JOI16_selling_rna) C++14
35 / 100
1500 ms 495068 KB
#include <bits/stdc++.h>
#define lsb(x) (x & (-x))
#define ll long long
#define ull unsigned long long
// 217
// 44

using namespace std;

struct Fenwick {
    vector <int> aib;
    int n;
    inline void init(int _n) {
        n = _n;
        aib.resize(n + 1);
    }
    inline void update(int pos, int val) {
        for(int i = pos; i <= n; i += lsb(i)) {
            aib[i] += val;
        }
    }
    inline int query(int pos) {
        int ans = 0;
        for(int i = pos; i > 0; i -= lsb(i)) {
            ans += aib[i];
        }
        return ans;
    }
};

struct Trie {

    Trie *son[26];
    int sz;
    vector <int> pos;

    Trie() {
        memset(son, NULL, sizeof(son));
        sz = 0;
    }

};

Trie *root1 = new Trie;
Trie *root2 = new Trie;

void add(Trie *nod, string &str, int p, int id) {
    if(p == str.size()) {
        nod -> sz++;
        nod -> pos.push_back(id);
    }
    else {
        int ch = str[p] - 'A';
        if(nod -> son[ch] == NULL) {
            nod -> son[ch] = new Trie;
        }
        add(nod -> son[ch], str, p + 1, id);
        nod -> sz++;
    }
}

void dfs(Trie *nod, string &str, int &id) {
    reverse(str.begin(), str.end());
    for(auto it : nod -> pos) {
        add(root2, str, 0, ++id);
    }
    reverse(str.begin(), str.end());

    for(int ch = 0; ch < 26; ch++) {
        if(nod -> son[ch] != NULL) {
            str.push_back(ch + 'A');
            dfs(nod -> son[ch], str, id);
            str.pop_back();
        }
    }
}

void query(Trie *nod, string &str, int p, pair <int, int> &cur) {
    if(nod == NULL) {
        cur = {2, 1};
        return ;
    }

    if(p == str.size()) {
        cur.second = cur.first + nod -> sz;
        cur.first++;
    }
    else {
        int ch = str[p] - 'A';
        for(int i = 0; i < ch; i++) {
            if(nod -> son[i] != NULL) {
                cur.first += nod -> son[i] -> sz;
            }
        }
        cur.first += nod -> pos.size();
        query(nod -> son[ch], str, p + 1, cur);
    }
}


void dfs1(Trie *nod, vector <int> &arr) {
    for(auto it : nod -> pos) {
        arr.push_back(it);
    }

    for(int ch = 0; ch < 26; ch++) {
        if(nod -> son[ch] != NULL) {
            dfs1(nod -> son[ch], arr);
        }
    }
}


struct Query {
    int pos, val;
    char sign;
    int id;
    bool operator <(const Query &other) const {
        return pos < other.pos;
    }
};


int main() {
    //ifstream cin("A.in");
    //ofstream cout("A.out");
    int i, n, m;
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);

    cin >> n >> m;

    for(i = 1; i <= n; i++) {
        string str;
        cin >> str;
        add(root1, str, 0, i);
    }

    string str;
    int id = 0;
    dfs(root1, str, id);

    vector <int> arr(1);
    dfs1(root2, arr);

    vector <Query> qry;

    for(i = 1; i <= m; i++) {
        string a, b;
        cin >> a >> b;

        reverse(b.begin(), b.end());

        pair <int, int> cur1, cur2;
        cur1 = cur2 = {0, 0};

        query(root1, a, 0, cur1);
        query(root2, b, 0, cur2);

        if(cur1.first <= cur1.second && cur2.first <= cur2.second) {

            qry.push_back({cur2.first - 1, cur1.first - 1, 1, i});
            qry.push_back({cur2.first - 1, cur1.second, -1, i});
            qry.push_back({cur2.second, cur1.first - 1, -1, i});
            qry.push_back({cur2.second, cur1.second, 1, i});

        }
        //cerr << cur1.first << " " << cur1.second << " " << cur2.first << " " << cur2.second << "\n";
    }

    Fenwick fen; fen.init(n);
    sort(qry.begin(), qry.end());

    vector <int> sol(m + 1);
    int pos = 0, sz = qry.size();

    for(i = 0; i <= n; i++) {
        if(i > 0) {
            fen.update(arr[i], 1);
        }
        while(pos < sz && qry[pos].pos <= i) {
            sol[qry[pos].id] += qry[pos].sign * fen.query(qry[pos].val);
            pos++;
        }
    }

    for(i = 1; i <= m; i++) {
        cout << sol[i] << "\n";
    }

    //cin.close();
    //cout.close();
    return 0;
}



/*void print(Trie *nod) {
    for(auto it : nod -> pos) {
        cerr << it << " ";
    }
    cerr << "\n";
    for(int ch = 0; ch < 26; ch++) {
        if(nod -> son[ch] != NULL) {
            print(nod -> son[ch]);
        }
    }
}*/

Compilation message

selling_rna.cpp: In constructor 'Trie::Trie()':
selling_rna.cpp:38:38: warning: passing NULL to non-pointer argument 2 of 'void* memset(void*, int, size_t)' [-Wconversion-null]
         memset(son, NULL, sizeof(son));
                                      ^
selling_rna.cpp: In function 'void add(Trie*, std::__cxx11::string&, int, int)':
selling_rna.cpp:48:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if(p == str.size()) {
        ~~^~~~~~~~~~~~~
selling_rna.cpp: In function 'void dfs(Trie*, std::__cxx11::string&, int&)':
selling_rna.cpp:64:14: warning: unused variable 'it' [-Wunused-variable]
     for(auto it : nod -> pos) {
              ^~
selling_rna.cpp: In function 'void query(Trie*, std::__cxx11::string&, int, std::pair<int, int>&)':
selling_rna.cpp:84:10: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     if(p == str.size()) {
        ~~^~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 2 ms 384 KB Output is correct
2 Correct 2 ms 384 KB Output is correct
3 Correct 2 ms 384 KB Output is correct
4 Correct 2 ms 384 KB Output is correct
5 Correct 2 ms 384 KB Output is correct
6 Correct 3 ms 384 KB Output is correct
7 Correct 3 ms 384 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 750 ms 495068 KB Output is correct
2 Correct 660 ms 472580 KB Output is correct
3 Execution timed out 1583 ms 489576 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 39 ms 5352 KB Output is correct
2 Correct 30 ms 4512 KB Output is correct
3 Correct 40 ms 6280 KB Output is correct
4 Correct 27 ms 5512 KB Output is correct
5 Correct 29 ms 4764 KB Output is correct
6 Correct 31 ms 6256 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 384 KB Output is correct
2 Correct 2 ms 384 KB Output is correct
3 Correct 2 ms 384 KB Output is correct
4 Correct 2 ms 384 KB Output is correct
5 Correct 2 ms 384 KB Output is correct
6 Correct 3 ms 384 KB Output is correct
7 Correct 3 ms 384 KB Output is correct
8 Correct 750 ms 495068 KB Output is correct
9 Correct 660 ms 472580 KB Output is correct
10 Execution timed out 1583 ms 489576 KB Time limit exceeded
11 Halted 0 ms 0 KB -