• Trie刷题


    • P3879 [TJOI2010]阅读理解
      虽然不需要用trie,但是秉着练习需要,就强行加上trie,没想到其中收获了stl的应用熟练度。首先想的是用set来存取在哪一行,但是可是要求加上结尾不换行,那么在遍历的时候我有很喜欢写for (auto it:se[p]),显然如果我判断it == se[p].end()是不正确的,因为it是int。如果判断it==*se[p].end()好像也不行,于是就写了for循环。
    #include <iostream>
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e6 + 9;
    set<int> se[N];
    struct AC {  
        int tr[N][27], idx = 0;
        string str;
        void insert(int x) {
            int p = 0;
            for (int i = 0; str[i]; i ++) {
                int id = str[i] - 'a';
                if (!tr[p][id])tr[p][id ] = ++ idx;
                p = tr[p][id];
            }
            se[p].insert(x);
        }
    }T;
    int main() {
        int n;
        cin >> n;
        for (int i =1 ; i <= n; i ++) {
            int cnt;cin >> cnt;
            while (cnt--) {
                cin >> T.str;
                T.insert(i);
            }
        }
        int m;cin >> m;
        for (int i = 1; i <= m; i ++) {
            cin >> T.str;
            int p = 0;
            bool f = 0;
            for (int j = 0; T.str[j]; j ++) {
                int id = T.str[j] - 'a';
                if (id < 0||id >= 26) {f = 1;break;}
                if (!T.tr[p][id]) {f = 1;break;}
                p = T.tr[p][id];
            }
            if (f||se[p].size() == 0) {cout << endl;continue;}
            auto cmp = se[p].end();
            cmp--;
            for (auto it = se[p].begin(); it != se[p].end();it++){
                if (it == cmp) {
                    cout << *it <<"
    ";
                } else 
                    cout << *it <<" ";
            }
        }
    }
    
    • HDU6955 Xor sum多校1 .vj
      小思维就是求异或和大于等于k的最短区间。然后就是可以转化的是,异或前缀和,然后就可以把异或前缀和放入字典树,然后字典树上节点维护所能到达的最右边的位置,然后查询即可,困难在于实现。
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    const ll N = 1e5 + 9;
    const ll inf = 0x3f3f3f3f;
    struct trie {
        ll tr[N *30][2], idx, r[N*30 ];
        void init() {
            // memset(r, -1, sizeof r);
            // memset(tr, 0, sizeof tr);
            for (int i = 0; i <= idx; i ++) {
                tr[i][0] = tr[i][1] = 0;
                r[i] = -1;
            }
            idx = 0;
        }
        void insert(ll x, ll pos){
            ll p = 0;
            bool f = 0;
            for (ll i = 32; i >= 0; i--) {
                ll id = (x >> i)&1;
                if (!tr[p][id])tr[p][id] = ++idx;
                p = tr[p][id];
                if (id == 1) f = 1;
                if (f)
                r[p] = pos;
            }
        }
        int ask(ll k,ll sum) {
            ll maxr1 = -1, maxr2 =-1;
            ll p = 0;
            bool f = 0;
            for (ll i = 32; i >=0; i --) {
                ll id1 = (k >> i) & 1;
                ll id2 = (sum >> (i)) & 1;
                if (id1 == 1) {
                    //maxr1 = max(maxr1, r[tr[p][id2 ^ 1]]);
                    p = tr[p][id2^1];
                } else {
                        maxr2 = max(maxr2, r[tr[p][id2 ^ 1]]);
                        //maxr1 = max(maxr1, r[tr[p][id2]]);
                    p = tr[p][id2];
                }
                if (!p) return max(r[p], maxr2);
            }
            return max(r[p], maxr2);
        }
    }T;
    ll a[N];
    ll sum[N];
    void solve() {
        int n, k;
        T.init();
        scanf("%d%d", &n, &k);
        ll sum = 0;
        ll len = 9999999999999, ansl = 0, ansr = 0;
        for (int i = 1; i <=n; i++) {
            ll x;scanf("%lld", &x);
            sum ^= x;
            int pos = T.ask(k , sum);
            T.insert(sum, i);
            //cout << sum << " ";
            if (pos == -1)continue;
            if (i - pos + 1 <= 0)continue;
            if (len > i - pos+1) {len = i-pos + 1;ansl = pos, ansr = i;}
        }
        /*----------------------------------------------------------------
        3 2 1 3 7 7 4 1 0 
        */
        if (len <=0||(ansl ==ansr && ansr == 0)) puts("-1"); 
        else printf("%lld %lld
    ", ansl + 1 , ansr);
    }
    signed main() {
       // freopen("in.txt", "r", stdin);
       // freopen("out.out", "w", stdout);
        clock_t start_time=clock();
       ll t = 1;scanf("%lld", &t);
       while (t--) {
          solve();
       }
       clock_t end_time=clock();
       //cout<< "Running time is: "<<static_cast<double>(end_time-start_time)/CLOCKS_PER_SEC*1000<<"ms"<<endl;//输出运行时间
    }
    
  • 相关阅读:
    20181123(编码问题)
    20181122笔记(列表、元组、字典和集合的数据类型及内置方法)
    20181121笔记(for,数字类型和字符串类型的内置方法)
    20181120笔记
    Python的第3堂课
    错误集合(想起来就更新)
    Python的第二堂课(2)
    Python的第二堂课(1)
    boost::bind实践2——来自《Beyond the C++ Standard Library ( An Introduction to Boost )》
    boost::bind实践
  • 原文地址:https://www.cnblogs.com/Xiao-yan/p/15168957.html
Copyright © 2020-2023  润新知