牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)
牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)
链接:https://ac.nowcoder.com/acm/problem/15706
现在需要您来帮忙维护这个名册,支持下列 4 种操作:
- 插入新人名 si,声望为 a
- 给定名字前缀 pi 的所有人的声望值变化 di
- 查询名字为 sj 村民们的声望值的和(因为会有重名的)
- 查询名字前缀为 pj 的声望值的和
题解:一个非常明显的线段树操作,前缀可以看作是区间更新,区间查询,给定名字就是单点更新,单点查询,字典树上dfs序可以得到将树型结构变成一个线性的结构,然后用线段树维护即可,比较好的码力题了
/**
* ┏┓ ┏┓
- ┏┛┗━━━━━━━┛┗━━━┓
- ┃ ┃
- ┃ ━ ┃
- ┃ > < ┃
- ┃ ┃
- ┃... ⌒ ... ┃
- ┃ ┃
- ┗━┓ ┏━┛
- ┃ ┃ Code is far away from bug with the animal protecting
- ┃ ┃ 神兽保佑,代码无bug
- ┃ ┃
- ┃ ┃
- ┃ ┃
- ┃ ┃
- ┃ ┗━━━┓
- ┃ ┣┓
- ┃ ┏┛
- ┗┓┓┏━┳┓┏┛
- ┃┫┫ ┃┫┫
- ┗┻┛ ┗┻┛
*/
// warm heart, wagging tail,and a smile just for you!
//
// ooOoo
// o8888888o
// 88" . "88
// (| -_- |)
// O\ = /O
// /---'\____ // .' \| |//.
// / ||| : |||//
// / ||||| -:- |||||-
// | | \ - /// | |
// | _| ''---/'' | |
// \ .-_-/-. /
//. .' /--.--\. . __
// ."" '<.___\_<|>_/___.' >'"". // | | :- `.;\ _ /;./ -: | |
// \ \-. \_ __\ /__ _/ .-/ /
// ======-.____-._/.-____.-'====== //=---='
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// 佛祖保佑 永无BUG
include
include
include
include
include
include
include
include
include
include
include
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
define ls rt<<1
define rs rt<<1|1
define lson l,mid,rt<<1
define rson mid+1,r,rt<<1|1
define bug printf("*********\n")
define FIN freopen("input.txt","r",stdin);
define FON freopen("output.txt","w+",stdout);
define IO ios::sync_with_stdio(false),cin.tie(0)
define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
const double Pi = acos(-1);
LL gcd(LL a, LL b) {
return b ? gcd(b, a % b) : a;
}
LL lcm(LL a, LL b) {
return a / gcd(a, b) * b;
}
double dpow(double a, LL b) {
double ans = 1.0;
while(b) {
if(b % 2)ans = ans * a;
a = a * a;
b /= 2;
} return ans;
}
LL quick_pow(LL x, LL y) {
LL ans = 1;
while(y) {
if(y & 1) {
ans = ans * x % mod;
} x = x * x % mod;
y >>= 1;
} return ans;
}
struct Trie {
int nxt[maxn][26], tot;
int in[maxn], out[maxn], time_tag;
void init() {
memset(nxt, 0, sizeof(nxt));
tot = 1;
time_tag = 0;
}
void insert(string str) {
int p = 1;
int len = str.length();
for(int i = 0; i < len; i++) {
int ch = str[i] - 'a';
if(!nxt[p][ch]) {
nxt[p][ch] = ++tot;
}
p = nxt[p][ch];
}
}
int query(string str) {
int p = 1;
int len = str.length();
for(int i = 0; i < len; i++) {
int ch = str[i] - 'a';
if(!nxt[p][ch]) {
return 0;
}
p = nxt[p][ch];
}
return p;
}
void dfs(int u) {
in[u] = ++time_tag;
for(int i = 0; i < 26; i++) {
if(nxt[u][i]) {
dfs(nxt[u][i]);
}
}
out[u] = time_tag;
}
} trie;
LL sum[maxn << 2];
int lazy[maxn << 2];
int cnt[maxn << 2];
void push_up(int rt) {
sum[rt] = sum[ls] + sum[rs];
cnt[rt] = cnt[ls] + cnt[rs];
}
void build(int l, int r, int rt) {
sum[rt] = lazy[rt] = 0;
if(l == r) return;
int mid = (l + r) >> 1;
build(lson);
build(rson);
}
void push_down(int rt, int len) {
if(lazy[rt]) {
lazy[ls] += lazy[rt];
lazy[rs] += lazy[rt];
sum[ls] += lazy[rt] * cnt[ls];
sum[rs] += lazy[rt] * cnt[rs];
lazy[rt] = 0;
}
}
void update_pos(int pos, int val, int l, int r, int rt) {
if(l == r) {
sum[rt] += val;
cnt[rt]++;
return;
}
int mid = (l + r) >> 1;
push_down(rt, r - l + 1);
if(pos <= mid) update_pos(pos, val, lson);
else update_pos(pos, val, rson);
push_up(rt);
}
void update(int L, int R, int val, int l, int r, int rt) {
if(L <= l && r <= R) {
sum[rt] += cnt[rt] * val;
lazy[rt] += val;
return;
}
int mid = (l + r) >> 1;
push_down(rt, r - l + 1);
if(L <= mid) update(L, R, val, lson);
if(R > mid) update(L, R, val, rson);
push_up(rt);
}
LL query(int L, int R, int l, int r, int rt) {
if(L <= l && r <= R) {
return sum[rt];
}
int mid = (l + r) >> 1;
push_down(rt, r - l + 1);
LL ans = 0;
if(L <= mid) ans += query(L, R, lson);
if(R > mid) ans += query(L, R, rson);
return ans;
}
int op[maxn];
char buf[maxn];
string str[maxn];
int val[maxn];
int main() {
ifndef ONLINE_JUDGE
FIN
endif
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d %s", &op[i], buf);
str[i] = buf;
if(op[i] <= 2) {
scanf("%d", &val[i]);
}
}
trie.init();
for(int i = 1; i <= n; i++) {
if(op[i] == 1) {
trie.insert(str[i]);
// cout << str[i] << endl;
}
}
trie.dfs(1);
// bug;
int tot = trie.tot;
// debug1(tot);
build(1, tot, 1);
for(int i = 1; i <= n; i++) {
if(op[i] == 1) {
int u = trie.query(str[i]);
int pos = trie.in[u];
// debug1(pos);
update_pos(pos, val[i], 1, tot, 1);
// bug;
} else if(op[i] == 2) {
int u = trie.query(str[i]);
if(u) {
int l = trie.in[u];
int r = trie.out[u];
update(l, r, val[i], 1, tot, 1);
}
} else if(op[i] == 3) {
int u = trie.query(str[i]);
if(u) {
int l = trie.in[u];
int r = trie.in[u];
LL ans = query(l, r, 1, tot, 1);
printf("%lld\n", ans);
} else {
printf("0\n");
}
} else if(op[i] == 4) {
int u = trie.query(str[i]);
if(u) {
int l = trie.in[u];
int r = trie.out[u];
LL ans = query(l, r, 1, tot, 1);
printf("%lld\n", ans);
} else {
printf("0\n");
}
}
}
return 0;
}
牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)的更多相关文章
- 牛客多校第三场 G Removing Stones(分治+线段树)
牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...
- 牛客~~wannafly挑战赛19~A 队列
链接:https://www.nowcoder.com/acm/contest/131/A来源:牛客网 题目描述 ZZT 创造了一个队列 Q.这个队列包含了 N 个元素,队列中的第 i 个元素用 Qi ...
- 牛客Wannafly挑战赛23 B.游戏
游戏 题目描述 小N和小O在玩游戏.他们面前放了n堆石子,第i堆石子一开始有ci颗石头.他们轮流从某堆石子中取石子,不能不取.最后无法操作的人就输了这个游戏.但他们觉得这样玩太无聊了,更新了一下规则. ...
- 牛客练习赛 29 E 位运算?位运算!(线段树)
题目链接 牛客练习赛29E 对$20$位分别建立线段树.首先$1$和$2$可以合起来搞(左移右移其实是等效的) 用个lazy标记下.转移的时候加个中间变量. $3$和$4$其实就是区间$01$覆盖操 ...
- 牛客小白月赛16 H 小阳的贝壳 (差分+线段树)
链接:https://ac.nowcoder.com/acm/contest/949/H来源:牛客网 题目描述 小阳手中一共有 n 个贝壳,每个贝壳都有颜色,且初始第 i 个贝壳的颜色为 colico ...
- 牛客小白月赛12 H 华华和月月种树 (离线dfs序+线段树)
链接:https://ac.nowcoder.com/acm/contest/392/H 来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 131072K,其他语言2621 ...
- HDU 3974 Assign the task(DFS序+线段树单点查询,区间修改)
描述There is a company that has N employees(numbered from 1 to N),every employee in the company has a ...
- 牛客 Wannafly 挑战赛26D 禁书目录 排列组合 概率期望
原文链接https://www.cnblogs.com/zhouzhendong/p/9781060.html 题目传送门 - NowCoder Wannafly 26D 题意 放一放这一题原先的题面 ...
- 【牛客Wannafly挑战赛12】 题解
传送门:https://www.nowcoder.com/acm/contest/79#question 说是比赛题解,其实我只会前三题: 后面的一定补 T1 题意,在一个长度为n的时间内,问如何选择 ...
随机推荐
- JavaScript--兼容问题总结
以下兼容主要面向IE8以上的兼容. 一.window.navigator浏览器信息 <script> console.log(window.navigator); // 用户浏览器的类型 ...
- poj3261 后缀数组求重复k次可重叠的子串的最长长度
Milk Patterns Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13669 Accepted: 6041 Ca ...
- Effective C++: 02构造、析构、赋值运算
05:了解C++默默编写并调用哪些函数 1:一个空类,如果你自己没声明,编译器就会为它声明(编译器版本的)一个copy构造函数.一个copy assignment操作符和一个析构函数.此外如果你没有声 ...
- hdu 2412 Party at Hali-Bula【树形dp】
HDU 2412 和poj 2342(hdu 1520)差不多,多了一个判断最优解是(Yes)否(No)唯一.关键问题也在这个判断最优解是否唯一上. 先定义dp[u][2],表示选(dp[][1])或 ...
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛: B. Coin 【概率题】【数论】
Bob has a not even coin(就是一个不均匀的硬币,朝上的概率不一定是1/2), every time he tosses the coin, the probability tha ...
- Vue电商后台管理系统项目第1天-基本环境搭建&登录功能
基本环境搭建完成 安装npm包:npm -S i vue vue-router axios element-ui 配置Eslint: 打开设置,搜索Eslint拓展,然后将下面代码覆盖进去即可 { , ...
- LeetCode54 Spiral Matrix
题目: Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spira ...
- Linux Shell 教程
Shell 教程 Shell 是一个C语言编写的程序,他是用户使用Linux的桥梁,Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界面用户通 ...
- etcd 在超大规模数据场景下的性能优化
作者 | 阿里云智能事业部高级开发工程师 陈星宇(宇慕) 概述 etcd是一个开源的分布式的kv存储系统, 最近刚被cncf列为沙箱孵化项目.etcd的应用场景很广,很多地方都用到了它,例如kuber ...
- 模板—tarjan求割边
int dfn[MAXN],low[MAXN],cnt; void tarjan(int x,int edg) { low[x]=dfn[x]=++cnt; for(int i=f(x);i;i=n( ...