[THUSC2016]补退选 - Trie

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\n", last = tr.query(s, k, len));
    }
  }
  return 0;
}

原文地址:https://www.cnblogs.com/newbielyx/p/12146402.html

时间: 2024-10-17 06:54:58

[THUSC2016]补退选 - Trie的相关文章

BZOJ 4896 :[Thu Summer Camp2016]补退选 Trie树+Vector

4896: [Thu Summer Camp2016]补退选 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 315  Solved: 97[Submit][Status][Discuss] Description X是T大的一名老师,每年他都要教授许多学生基础的C++知识.在T大,每个学生在每学期的开学前都需要选课,每 次选课一共分为三个阶段:预选,正选,补退选:其中"补退选"阶段最忙碌.在补退选阶段,学生即可以选课,也 可以退课.对于

【BZOJ4896】[Thu Summer Camp2016]补退选 Trie树

[BZOJ4896][Thu Summer Camp2016]补退选 Description X是T大的一名老师,每年他都要教授许多学生基础的C++知识.在T大,每个学生在每学期的开学前都需要选课,每 次选课一共分为三个阶段:预选,正选,补退选:其中"补退选"阶段最忙碌.在补退选阶段,学生即可以选课,也 可以退课.对于X老师来说,在补退选阶段可能发生以下两种事件: 1:一个姓名为S的学生选了他的课(姓名S将出现在X的已选课学生名单中) 2:一个姓名为S的学生退了他的课(姓名S将从X的已

bzoj4896 补退选

Description X是T大的一名老师,每年他都要教授许多学生基础的C++知识.在T大,每个学生在每学期的开学前都需要选课,每 次选课一共分为三个阶段:预选,正选,补退选:其中"补退选"阶段最忙碌.在补退选阶段,学生即可以选课,也 可以退课.对于X老师来说,在补退选阶段可能发生以下两种事件: 1:一个姓名为S的学生选了他的课(姓名S将出现在X的已选课学生名单中) 2:一个姓名为S的学生退了他的课(姓名S将从X的已选课学生名单中移除) 同时,X老师对于有哪些学生选了他的课非常关心,所

BZOJ4896 [Thu Summer Camp2016]补退选

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目链接:BZOJ4896 正解:$Trie+vector$ 解题报告: $THUSC2016$ $T2$ 考虑每次加入删除对出现次数的影响只会加减一,那么我可以先用$Trie$来维护整个问题中出现的字符串,然后对于每个节点我都记录一下以当前串为前缀的字符

【bzoj4896】补退选

傻逼题. 每个点维护下vector,然后随便做. #include<bits/stdc++.h> const int N=300000; using namespace std; typedef long long ll; struct Node{ int ch[20],size; vector<int> c; }t[N]; int n,cnt,ans,len;char s[200]; inline int read(){ int f=1,x=0;char ch; do{ch=ge

# 清北冬令营真题泛做

清北冬令营真题泛做 前言 这段时间为了准备冬令营把清北冬令营真题都做了一下.更个博回顾一下(免得你们老说我咕咕咕). 先写良心PKU的题再写THU的题, 主要是THU的题和PKU比起来真的毒瘤好多...... PKUWC2018 [PKUWC2018]Minimax 一个比较显然的暴力是归并排序,每次直接前后缀计算答案即可. 为啥不用线段树合并代替归并排序呢? 暴力线段树合并,合并的过程中顺便算一下即可,由于权值区间不交所以复杂度一个\(log\). [PKUWC2018]Slay the Sp

THUSC2016 游记

浑浑噩噩地就出发了,只记得可以翘课,不知道自己要干什么去. Day 0    5点起床,到潮汕机场坐飞机.第一次坐飞机非常不爽起飞和降落时的加速度……终于还是转转地铁.动车在下午4点左右抵达目的地,西郊宾馆.按事先的安排和Ccz住双人房.北京的红绿灯好奇怪啊,红灯刚过,绿灯就开始闪,闪了很久也没变化……晚上KPM出去浪,Czl来我们房间玩,于是我们在他电脑上玩去<疯狂小人战斗>,考前回归一发童年.(3P 3个键盘真爽) Day 1    6点醒,吃了顿挺不错的早餐,就坐车去THU了,200号人

软件概要设计文档(终)

软件概要设计文档 1.引言 1.1目的 该文档的目的是描述辅助选课系统的概要设计,主要内容包括系统功能简介.系统结构设计.系统结构设计.系统接口设计.模块设计和界面设计等. 本文档预期的读者包括设计人员.开发人员.项目管理人员.测试人员. 1.2范围 1.2.1系统目标 开发一个支持学生选课并辅助学生选课的APP. 1.2.2主要软件需求 该系统主要功能包括: l  用户登录 l  用户选课 l  查看课表 l  辅助选课 l  信息更新 1.2.3软件设计约束 软件支持单键盘.单鼠标的物理结构

T2 选ID trie树

T2 选ID Description ? 机房似乎有许多人没有 ID,热心同志小 A 为了服务人民,所有决定帮大家找一个合适的 ID. ? 小 A 觉得一个合适的 ID,和这个人的相关程度应该是比较高的,就像他的 ID 里有他的名字缩写一样.为了量化这个相关程度,他定义一个人的名字 \(S\) 和他的 ID \(T\) 的匹配值的大小为\(lcp\)(\(S\),\(T\))?.现在有 \(n\) 个人,小 A 想好了 \(n\) 个 ID,他想知道如果把 ID 分配给机房众人,最后能够得到的最