2019 ICPC 南京 F. Paper Grading(字典树dfs序上树套树)

Paper Grading

题意:给定nnn个字符串,有两种操作:

一、给定i,ji, ji,j,交换第iii个跟第jjj个字符串。

二、给定 str ,k,l,rk, l, rk,l,r,问你在区间[l,r][l, r][l,r]中的字符,与 str 至少有kkk个公共前缀的字符串有多少个。

先建立一颗字典树,对于满足要求的字符串,我们可以在字典树中查找 str 的第 kkk 个字符落在的点rtrtrt

然后在以 rtrtrt 为根的子树上查找在区间[l,r][l, r][l,r]的字符有多少个,

考虑在字典树dfsdfsdfs序上,对每个节点建立一颗主席树,然后插入值,对于查询操作,我们只要查找两颗主席树上[l,r][l, r][l,r]区间的和即可。

但是因为有带修操作,所以考虑树状数组套主席树,这样即可满足带修跟查找操作,发现一直wa7wa\ 7wa 7,(据我判断应该是内存不够)。

所以考虑如何优化,对于字典树来说,总长度可以说是固定的2×1052 \times 10 ^ 52×105,但是对于nnn来说却是一般小于2×1052 \times 10 ^52×105的,对于上述的建树方式,

我们建立的主席树可以说也是固定的2×1052 \times 10 ^ 52×105棵,所以说整体来说是2×105log⁡nlog⁡n2 \times 10 ^ 5 \log n \log n2×105lognlogn

如果对每个字符串建立一颗主席树整体来说应该是nlog⁡2×105log⁡2×105n \log {2 \times 10 ^ 5} \log {2 \times 10 ^ 5}nlog2×105log2×105,在多数情况下应该是小于上着的。

所以对于查询我们只要对[l,r][l, r][l,r]区间,查询dfsdfsdfs序在l[rt],r[rt]l[rt], r[rt]l[rt],r[rt]之间的即可,对于修改操作我们交换i,ji, ji,j位置的dfsdfsdfs序即可。

#include <bits/stdc++.h>using namespace std;const int N = 2e5 + 10;int trie[N][26], cnt = 1;int pos[N], value[N], l[N], r[N], tot, n, m;int root[N], ls[N << 7], rs[N << 7], sum[N << 7], num;int insert(string &str) {int n = str.size(), rt = 1;for (int i = 0; i < n; i++) {if (!trie[rt][str[i] - 'a']) {trie[rt][str[i] - 'a'] = ++cnt;}rt = trie[rt][str[i] - 'a'];}return rt;
}void dfs(int rt) {l[rt] = ++tot;for (int i = 0; i < 26; i++) {if (trie[rt][i]) {dfs(trie[rt][i]);}}r[rt] = tot;
}void update(int &rt, int l, int r, int x, int v) {if (!rt) {rt = ++num;}sum[rt] += v;if (l == r) {return ;}int mid = l + r >> 1;if (x <= mid) {update(ls[rt], l, mid, x, v);}else {update(rs[rt], mid + 1, r, x, v);}
}int A[50], B[50], cnt1, cnt2;int query_sum(int l, int r, int L, int R) {if (l >= L && r <= R) {int ans = 0;for (int i = 1; i <= cnt1; i++) {ans -= sum[A[i]];}for (int i = 1; i <= cnt2; i++) {ans += sum[B[i]];}return ans;}int mid = l + r >> 1, ans = 0, A1[50], B1[50];if (L <= mid) {for (int i = 1; i <= cnt1; i++) {A1[i] = A[i];A[i] = ls[A[i]];}for (int i = 1; i <= cnt2; i++) {B1[i] = B[i];B[i] = ls[B[i]];}ans += query_sum(l, mid, L, R);for (int i = 1; i <= cnt1; i++) {A[i] = A1[i];}for (int i = 1; i <= cnt2; i++) {B[i] = B1[i];}}if (R > mid) {for (int i = 1; i <= cnt1; i++) {A1[i] = A[i];A[i] = rs[A[i]];}for (int i = 1; i <= cnt2; i++) {B1[i] = B[i];B[i] = rs[B[i]];}ans += query_sum(mid + 1, r, L, R);for (int i = 1; i <= cnt1; i++) {A[i] = A1[i];}for (int i = 1; i <= cnt2; i++) {B[i] = B1[i];}}return ans;
}inline int lowbit(int x) {return x & (-x);
}void add(int pos, int x, int v) {for (int i = pos; i <= n; i += lowbit(i)) {update(root[i], 1, tot, x, v);}
}int get_sum(int l, int r, int L, int R) {if (l > r || L > R) {return 0;}cnt1 = cnt2 = 0;for (int i = l - 1; i; i -= lowbit(i)) {A[++cnt1] = root[i];}for (int i = r; i; i -= lowbit(i)) {B[++cnt2] = root[i];}return query_sum(1, tot, L, R);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);cin >> n >> m;string str;for (int i = 1; i <= n; i++) {cin >> str;pos[i] = insert(str);}dfs(1);for (int i = 1; i <= n; i++) {pos[i] = l[pos[i]];value[i] = i;add(value[i], pos[i], 1);}for (int i = 1, op, k, a, b; i <= m; i++) {cin >> op;if (op == 1) {cin >> a >> b;add(value[a], pos[a], -1), add(value[b], pos[b], -1);swap(pos[a], pos[b]);add(value[a], pos[a], 1), add(value[b], pos[b], 1);}else {cin >> str >> k >> a >> b;int rt = 1;for (int j = 0; j < k; j++) {if (!trie[rt][str[j] - 'a']) {rt = -1;break;}rt = trie[rt][str[j] - 'a'];}if (rt == -1) {cout << "0\n";}else {cout << get_sum(a, b, l[rt], r[rt]) << "\n";}}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313882.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

细节之中自有天地,整洁成就卓越代码

溪源 | 长沙.NET技术社区开篇我们总是很容易就能写出满足某个特定功能的代码&#xff0c;却很难写出优雅代码。又最欣赏那些优雅的代码&#xff0c;因为优雅代码更能体现一个开发者的积累。就像写一篇散文&#xff0c;有的就像初学者不得其门而入&#xff0c;遣词造句都非常困难…

#2693. jzptab

jzptab ∑i1n∑j1mlcm(i,j)∑i1n∑j1mijgcd⁡(i,j)∑d1nd∑i1nd∑j1mdij[gcd⁡(i,j)1]∑d1nd∑k1ndk2μ(k)∑i1nkdi∑j1mkdjTkd,f(n)∑i1ni∑T1nf(nT)f(mT)(T∑k∣Tμ(k)k)设g(n)n∑d∣nμ(d)d先令g(n)g(n)ng(1)1,g(p)μ(1)μ(p)p1−p,g(pk,k≥2)1−p同时是积性函数&#xff0c…

UTF8、UTF16、UTF32区别

UTF8、UTF16、UTF32都是unicode字符集的字符编码。 UTF意思是unicode转换格式&#xff08;Unicode transform format&#xff09;&#xff0c;出现UTF8、UTF16、UTF32是出于要在内存中存储字符的目的而对unicode字符编号进行编码。 UTF8、UTF16、UTF32区别&#xff1a;&#…

URL编解码、Big Endian和Little Endian

一、Endian的起源 在各种计算机体系结构中&#xff0c;对于字节、字等的存储机制有所不同&#xff0c;因而引发了计算机通信领域中一个很重要的问题&#xff0c;即通信双方交流的信息单元&#xff08;比特、字节、字、双字等等&#xff09;应该以什么样的顺序进行传送。如果不达…

一次业务网关用ASP.NET Core 2.1重构的小结

前言对于API网关&#xff0c;业界貌似对它进行下划分&#xff0c;有下面几个分类/场景。面向Web App面向Mobile App面向Partner OpenAPI面向Partner ExternalAPI其他。。。在18年8月份的时候&#xff0c;有幸用.NET Core 2.1重构了一个对外的业务网关项目&#xff0c;这个项目的…

导数卷积 (NTT)

导数卷积 有f(x)∑i0n−1aixi求g(x)∑i0n−1f(i)(x)f(n−i−1)(x)∑i0n−1∑j0n−1aij(ij)!j!∑k0n−1ak(n−i−1)(k(n−i−1))!k!设F(n)ann!我们单独求解g(x)的第m项&#xff0c;有gm∑i0n−1∑j1d(F(ij)∗F(n−i−1d−j))(1j!∗1(d−j)!)设H(n)1n!有f(x) \sum_{i 0} ^{n - …

Java如何解决乱码问题

java在字符串中统一用Unicode表示。 对于任意一个字符串&#xff1a;String string “测试字符串”; 如果源文件是GBK编码&#xff0c;操作系统默认环境编码也为GBK&#xff0c;那么编译的时候&#xff0c;JVM将按照GBK编码将字节数组解析为字符&#xff0c;然后将字符转换为…

推荐几个华为,字节跳动、蚂蚁金服等大佬的公众号

每一个公众号都是一个特色的图书馆&#xff0c;为我们的学习提供优质的服务&#xff0c;珍贵的资源&#xff0c;耐心看完&#xff0c;认真选择适合自己的良师益友吧。Python爱好者社区Python爱好者社区&#xff0c;这里有分类整理好的历史优秀文章数千篇供你学习&#xff0c;内…

HDU 6061 RXD and functions(NTT)

RXD and functions 首先是有一个结论&#xff0c;对多项式做任意多次 transformation &#xff0c;其结果跟做一次 transformation Tr(f,∑i1mai)Tr(f, \sum\limits_{i 1} ^{m} a_i)Tr(f,i1∑m​ai​)的结果是一样的&#xff0c;所以我们约定a−∑i1maia -\sum\limits_{i 1…

Java语法糖

Java中语法糖原理、解语法糖 语法糖&#xff1a;switch 支持 String 与枚举、泛型、自动装箱与拆箱、方法变长参数、枚举、内部类、条件编译、 断言、数值字面量、for-each、try-with-resource、Lambda表达式、 先Mark&#xff0c;需要后续补齐、 参考&#xff1a; https://w…

使用Ingress来负载分发微服务

目录 使用Ingress来负载分发微服务 Demo规划 准备Demo并完成部署 创建部署&#xff08;Deployment&#xff09;资源 创建服务&#xff08;Service&#xff09;资源 创建Ingress资源并配置转发规则 使用Ingress来负载分发微服务NodePort Service存在太多缺陷&#xff0c;不适合…

伯努利数(详解 + 例题 :P3711 仓鼠的数学题)

伯努利数 定义Sk(n)∑i0n−1ikS_k(n) \sum\limits_{i 0} ^{n - 1} i ^ kSk​(n)i0∑n−1​ik。 从二项式出发 (01)k1∑i0kCk1i0i0k1⋮(n−11)k1∑i0kCk1i(n−1)i(n−1)k1把次方k1的移项&#xff0c;再整体相加&#xff0c;得nk1∑i0kCk1iSi(n)nk1∑i0k−1Ck1iSi(n)(k1)Sk(n…

并发和并行及多线程基本概念

并发&#xff08;Concurrent&#xff09; 在操作系统中&#xff0c;是指一个时间段中有几个程序都处于已启动运行到运行完毕之间&#xff0c;且这几个程序都是在同一个处理机上运行&#xff0c;但任一个时刻点上只有一个程序在处理机上运行。 并发&#xff0c;本质上是一个物理…

XUnit 依赖注入

XUnit 依赖注入Intro现在的开发中越来越看重依赖注入的思想&#xff0c;微软的 Asp.Net Core 框架更是天然集成了依赖注入&#xff0c;那么在单元测试中如何使用依赖注入呢&#xff1f;本文主要介绍如何通过 XUnit 来实现依赖注入&#xff0c; XUnit 主要借助 SharedContext 来…

P3711 仓鼠的数学题(伯努利数)

P3711 仓鼠的数学题 有关伯努利数的知识可以看我的上一篇题解链接&#xff08;写的超详细&#xff09;。 F(x)∑k0nSk(x)ak原本定义的Sk(x)∑i0xik根据伯努利数的定义Sk′(x)∑i0x−1ik则我们求F(x)∑k0nSk′(x)ak,答案即为F(x1)考虑先求F(x)∑k0nak1k1∑i0kCk1iBixk−i1∑k0n…

程序员自家种水果,新鲜包邮配送!

点击上面“蓝字”关注我们&#xff01;上次猕猴桃的活动一经推出&#xff0c;得到了广大粉丝的支持&#xff0c;我感到十分欣慰&#xff0c;非常感谢大家对我的信任。好多小伙伴&#xff0c;买了一箱尝过后又下单了好几箱。事实证明&#xff0c;品质才是销量的最佳保证。有些粉…

实现一个简单的基于码云(Gitee) 的 Storage

实现一个简单的基于码云(Gitee) 的 StorageIntro上次在 asp.net core 从单机到集群 一文中提到存储还不支持分布式&#xff0c;并立了一个 flag基于 github 或者 开源中国的码云实现一个 storage于是这两天就来填坑了。。实现了一个简单的基于开源中国的码云的 storage准备工作…

Java多线程的4种实现方式

** Java多线程的4种实现方式 ** 1&#xff1a;继承Thread并重写run方法&#xff0c;并调用start方法 /*** Java实现多线程的方式1* 继承Thread类&#xff0c;重写run方法* author hongbo.zhao 2019年4月12日 上午7:12:35*/ class MyThread extends Thread {Overridepublic …

采蘑菇的克拉莉丝(树链剖分)

采蘑菇的克拉莉丝 一个有点意思的树链剖分的题。 题意&#xff1a; 一棵树&#xff0c;有两种操作&#xff1a; ①&#xff1a;在点vvv放xxx个蘑菇。 ②&#xff1a;将起点变为vvv。 每次计算收集所有蘑菇的代价。 收集蘑菇的代价为&#xff0c;起点到所在蘑菇的路径上的…

HDU 6428 Problem C. Calculate(积性函数)

Problem C. Calculate ϕϕ∗ϵϕ∗μ∗Iϕ(n)∑d∣n(ϕ∗μ)(d)设g(n)∑d∣n(ϕ∗μ)(d)∑i1A∑j1B∑k1Cϕ(gcd(i,j2,k3))∑i1A∑j1B∑k1C∑d∣i,d∣j2,d∣k3(ϕ∗μ)(d)∑d1A(ϕ∗μ)(d)∑i1A∑j1B∑k1C[d∣i,d∣j2,d∣k3]\phi \phi * \epsilon \phi * \mu * I\\ \phi(n) …