• Wannafly挑战赛14 B 字典树


    B 前缀查询

    题目描述
    在一个 Minecraft 村庄中,村长有这一本小写字母构成的名册(字符串的表),
    每个名字旁边都记录着这位村民的声望值,而且有的村民还和别人同名。
    随着时间的推移,因为没有村民死亡,这个名册变得十分大。
    现在需要您来帮忙维护这个名册,支持下列 4 种操作:

    1. 插入新人名 si,声望为 ai
    2. 给定名字前缀 pi 的所有人的声望值变化 di
    3. 查询名字为 sj 村民们的声望值的和(因为会有重名的)
    4. 查询名字前缀为 pj 的声望值的和
      输入描述:

    第一行为两个整数 0 ≤ N ≤ 105,表示接下来有 N 个操作;
    接下来 N 行,每行输入一个操作,行首为一个整数 1 ≤ oi ≤ 4,表示这一行的操作的种类,
    那么这一行的操作和格式为:

    1. 插入人名,这一行的格式为 1 si ai,其中 |ai| ≤ 103
    2. 前缀修改声望,这一行的格式为 2 pi di,其中 |di| ≤ 103
    3. 查询名字的声望和,这一行的格式为 3 sj
    4. 查询前缀的声望和,这一行的格式为 4 pj
      输入保证插入人名的字符串的长度和小于或等于 105,总的字符串的长度和小于或等于 106。

    输出描述:

    对于每一次询问操作,在一行里面输出答案。

    示例1
    输入

    20
    1 a -10
    1 abcba -9
    1 abcbacd 5
    4 a
    2 a 9
    3 aadaa
    3 abcbacd
    4 a
    3 a
    2 a 10
    3 a
    2 a -2
    2 d -8
    1 ab -2
    2 ab -7
    1 aadaa -3
    4 a
    3 abcba
    4 a
    4 c

    输出

    -14
    0
    14
    13
    -1
    9
    11
    1
    11
    0

    tags:
    裸裸的字典树,然后加个lazy 标记。

    //https://www.nowcoder.com/acm/contest/81/B
    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define rep(i,a,b) for (int i=a; i<=b; ++i)
    #define per(i,b,a) for (int i=b; i>=a; --i)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    #define MP make_pair
    #define PB push_back
    #define fi  first
    #define se  second
    typedef long long ll;
    const int N = 2000005;
    
    struct Item {
        ll  val1, val2, cnt1, cnt2, lazy;
    } p[N*3];
    int tr[N][27], Index;
    char s[N];
    void pushdown(int now) {
        rep(i,0,25) if(tr[now][i]) {
            int id = tr[now][i];
            p[id].val1 += p[now].lazy*p[id].cnt1;
            p[id].val2 += p[now].lazy*p[id].cnt2;
            p[id].lazy += p[now].lazy;
        }
        p[now].lazy = 0;
    }
    void Insert(ll x) {
        int len=strlen(s+1), now=0;
        for(int i=1; i<=len; ++i) {
            int id = s[i]-'a';
            if(tr[now][id]==0) tr[now][id] = ++Index;
            now = tr[now][id];
            if(p[now].lazy) pushdown(now);
            p[now].val1 += x,  ++p[now].cnt1;
        }
        p[now].val2 += x,  ++p[now].cnt2;
    }
    void update(ll x) {
        int len=strlen(s+1), now=0;
        for(int i=1; i<=len; ++i) {
            int id = s[i]-'a';
            if(tr[now][id]==0) tr[now][id] = ++Index;
            now = tr[now][id];
            if(p[now].lazy) pushdown(now);
        }
        int tnow = now;    now = 0;
        for(int i=1; i<=len; ++i) {
            now = tr[now][s[i]-'a'];
            p[now].val1 += x*p[tnow].cnt1;
        }
        p[now].lazy += x;
        p[now].val2 += x*p[now].cnt2;
    }
    ll  query1() {
        int len=strlen(s+1), now=0;
        for(int i=1; i<=len; ++i) {
            int id = s[i]-'a';
            if(tr[now][id]==0) return 0;
            now = tr[now][id];
            if(p[now].lazy) pushdown(now);
        }
        return p[now].val2;
    }
    ll  query2() {
        int len=strlen(s+1), now=0;
        for(int i=1; i<=len; ++i) {
            int id = s[i]-'a';
            if(tr[now][id]==0) return 0;
            now = tr[now][id];
            if(p[now].lazy) pushdown(now);
        }
        return p[now].val1;
    }
    int main()
    {
        int T;  scanf("%d", &T);
        int type;  ll x;
        while(T--)
        {
            scanf("%d", &type);
            if(type==1) {
                scanf("%s%lld", s+1, &x);
                Insert(x);
            }
            else if(type==2) {
                scanf("%s%lld", s+1, &x);
                update(x);
            }
            else if(type==3) {
                scanf("%s", s+1);
                printf("%lld
    ", query1());
            }
            else {
                scanf("%s", s+1);
                printf("%lld
    ", query2());
            }
        }
    
        return 0;
    }
    
  • 相关阅读:
    Mosquitto搭建Android推送服务(一)MQTT简介
    Quartz定时任务简单实例
    Oracle基础知识(一)、简介与安装
    [2013-08-01]window.open
    C#中DataTable与泛型集合互转(支持泛型集合中对象包含枚举)
    C#代码安装Windows服务(控制台应用集成Windows服务)
    Node+Socket实现聊天室
    web前端架构
    Laravel-admin form 表单是增加或者修改
    Laravel-admin 消息提醒、播放音频、点击跳转
  • 原文地址:https://www.cnblogs.com/sbfhy/p/9005209.html
Copyright © 2020-2023  润新知