zoukankan      html  css  js  c++  java
  • [THUSC2016]补退选

    Description

    维护一个字符串集合,有三种事件,加入一个字符串,删除一个字符串,询问最早在哪个事件之后,以某个串为前缀的字符串数量超过(k),强制在线。(n le 100000,|S| le 60),输入中的所有字符串只会包含前(10)个小写字母。

    Solution

    建立(Trie)树维护字符串集合,在(Trie)树上的每一个节点开一个(vector),用来记录子树内的结束节点到达某个值的最早时刻,查询时直接找到前缀对应节点即可。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    const int _ = 1e6 + 10;
    int N, tim;
    
    inline int ty() {
      char ch = getchar();
      int x = 0, f = 1;
      while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
      }
      while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
      }
      return x * f;
    }
    
    inline int getstr(char *s) {
      char ch = getchar();
      int cnt = 0;
      while (ch >= 'a' && ch <= 'j') {
        s[++cnt] = ch;
        ch = getchar();
      }
      return cnt;
    }
    
    struct Trie {
      int trie[_][10], cnt[_], tot;
      vector<int> num[_];
      void insert(char *s, int len) {
        int x = 0;
        for (int i = 1; i <= len; ++i) {
          int ch = s[i] - 'a';
          if (!trie[x][ch]) trie[x][ch] = ++tot;
          x = trie[x][ch];
          ++cnt[x];
          if (num[x].size() < cnt[x]) num[x].push_back(tim);
        }
      }
      void erase(char *s, int len) {
        int x = 0;
        for (int i = 1; i <= len; ++i) {
          int ch = s[i] - 'a';
          x = trie[x][ch];
          --cnt[x];
        }
      }
      int query(char *s, int k, int len) {
        int x = 0;
        for (int i = 1; i <= len; ++i) {
          int ch = s[i] - 'a';
          if (!trie[x][ch]) return -1;
          x = trie[x][ch];
        }
        if (num[x].size() <= k)
          return -1;
        else
          return num[x][k];
      }
    } tr;
    
    int main() {
    #ifndef ONLINE_JUDGE
      freopen("select.in", "r", stdin);
      freopen("select.out", "w", stdout);
    #endif
      N = ty();
      int last = 0;
      for (tim = 1; tim <= N; ++tim) {
        int op = ty();
        char s[65];
        int len = getstr(s);
        if (op == 1)
          tr.insert(s, len);
        else if (op == 2)
          tr.erase(s, len);
        else if (op == 3) {
          int a = ty(), b = ty(), c = ty();
          int k = (1ll * a * abs(last) + b) % c;
          printf("%d
    ", last = tr.query(s, k, len));
        }
      }
      return 0;
    }
    
  • 相关阅读:
    Java使用POI插件将数据以excel形式备份
    bzoj1611[Usaco2008 Feb]Meteor Shower流星雨*
    bzoj1603[Usaco2008 Oct]打谷机*
    bzoj1599[Usaco2008 Oct]笨重的石子*
    bzoj1230[Usaco2008 Nov]lites 开关灯*
    bzoj4002[JLOI2015]有意义的字符串
    bzoj1613[Usaco2007 Jan]Running贝茜的晨练计划*
    bzoj1602[Usaco2008 Oct]牧场行走*
    bzoj1715[Usaco2006 Dec]Wormholes 虫洞*
    bzoj2442[Usaco2011 Open]修剪草坪*
  • 原文地址:https://www.cnblogs.com/newbielyx/p/12146402.html
Copyright © 2011-2022 走看看